2012-12-24 21 views
11

Powiel możliwe:
Arithmetic operator overloading for a generic class in C#Operator przeciążenie z rodzajowych

Oto kod dla rodzajowego klasy I zostały utworzone, aby dodać liczbę zespoloną przeciążyć operatora.

public class Complex<T> 
{ 
    public T _a, _b; 
    public Complex(T i, T j) 
    { 
     _a = i; 
     _b = j; 
    } 
    public static Complex<T> operator +(Complex<T> i, Complex<T> j) 
    { 
     return new Complex<T>(i._a + j._a, i._b + j._b); 
    } 
} 

podczas pracy z tym mam na błędzie,

Error: Operator '+' cannot be applied to operands of type 'T' and 'T' 

może ktoś zaproponować mi sposób mogę użyć operatora przeciążenia z rodzajowych?

+1

http://stackoverflow.com/questions/756954/arithmetic-operator-overloading-for-a-eneric-class-in- c-sharp – Habib

+0

, a także: http://stackoverflow.com/questions/147646/solution-for-overloaded-operator-constraint-in-net-generics Brak możliwości zdefiniowania typów wartości przy przeciążeniu operatora jest poważnym ograniczeniem C# . Po prostu nie ma żadnej satysfakcjonującej pracy. – citykid

+0

To nie powinno być ogólne. Uogólniaj tylko generyczne, gdy ma się ** tam ** dowolny typ; dlatego nazywają się * generics *. –

Odpowiedz

22

Problem polega na tym, że kompilator nie może stwierdzić, czy operator + można zastosować do . Niestety, nie ma sposobu, aby ograniczyć T, aby być typem numerycznym w języku C#.

Jednakże, może być w stanie obejść ten pomocą dynamicznego środowiska wykonawczego:

public class Complex<T> where T : struct 
{ 
    public T _a, _b; 
    public Complex(T i, T j) 
    { 
     _a = i; 
     _b = j; 
    } 
    public static Complex<T> operator +(Complex<T> i, Complex<T> j) 
    { 
     return new Complex<T>(Sum(i._a, j._a), Sum(i._b, j._b)); 
    } 

    private static T Sum(T a, T b) 
    { 
     return (dynamic)a + (dynamic)b; 
    } 
} 
+0

Wow. Wiele razy widziałem to pytanie, ale nigdy nie widziałem tej odpowiedzi. Powróciłem do emitowania kodów op w przeszłości, aby zrobić to, co wydaje się wykonywać "(dynamiczny)". Ciekawy. – ja72

0

Nie można podsumować dwóch ogólnych typów obiektów; w funkcji statycznej próbujesz dodać dwa elementy typu T i._a i j._a., ale T może być dowolnego typu, co spróbujesz zrobić?

2

Jeśli chcesz oszukać, można tymczasowo oznaczyć je jako dynamic rodzaju i pozwolić wykonawcze w celu określenia, jak to zrobić. Dopóki używany typ T definiuje operatora +, będzie działać. Oznacza to, że będzie działać zarówno dla liczb i łańcuchów, jak i dowolnego typu (niestandardowego lub innego); nie jestem pewien, czy to twoja intencja na Complex czy nie. Dodatkowo, jeśli nie ma operatora, który mógłby zastosować dźwignię, wyjątek zostanie wyrzucony w środowisku wykonawczym; nie ma sposobu (z tego co wiem), aby wykonać kompilację czasu sprawdzając to.

public class Complex<T> 
{ 
    public T _a, _b; 
    public Complex(T i, T j) 
    { 
     _a = i; 
     _b = j; 
    } 
    public static Complex<T> operator +(Complex<T> i, Complex<T> j) 
    { 
     dynamic d_i = i; 
     dynamic d_j = j; 
     return new Complex<T>(d_i._a + d_j._a, d_i._b + d_j._b); 
    } 
} 

wykorzystanie próbki z ciągów:

Complex<string> i = new Complex<string>("Hel", "Wor"); 
Complex<string> j = new Complex<string>("lo ", "ld!"); 

Complex<string> ij = i + j; 

Console.WriteLine(ij._a + ij._b); //Hello World! 
0

Jak wspomniano powyżej, można ograniczyć T być IConvertible a następnie użyć typu decimal aby wykonać żądaną funkcję matematyczną, co następuje:

public class Complex<T> where T : struct, IConvertible 
{ 
    public T _a, _b; 

    public Complex(T i, T j) 
    { 
     _a = i; 
     _b = j; 
    } 

    public static Complex<T> operator +(Complex<T> i, Complex<T> j) 
    { 
     return new Complex<T>(Sum(i._a, j._a), Sum(i._b, j._b)); 
    } 

    private static T Sum(T a, T b) 
    { 
     return (T)Convert.ChangeType(a.ToDecimal(CultureInfo.CurrentCulture) + b.ToDecimal(CultureInfo.CurrentCulture), typeof(T)); 
    } 
} 
Powiązane problemy