C # Aggiunta di due valori generici

Qualcuno può spiegare perché questo non funzionerà? Stavo cercando di essere in grado di aggiungere due valori indipendentemente dal tipo numerico.

public static T Add (T number1, T number2) { return number1 + number2; } 

Quando compilo questo, ottengo il seguente errore:

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

Non esiste un vincolo generico che consente di imporre il sovraccarico dell’operatore. Puoi dare un’occhiata alla seguente libreria . In alternativa, se si utilizza .NET 4.0, è ansible utilizzare la parola chiave dynamic :

 public static T Add(T number1, T number2) { dynamic a = number1; dynamic b = number2; return a + b; } 

Ovviamente questo non si applica alla sicurezza del tempo di compilazione, che è ciò per cui i generici sono destinati. L’unico modo per applicare la sicurezza in fase di compilazione è applicare i vincoli generici. E per il tuo scenario non c’è nessun vincolo disponibile. È solo un trucco per imbrogliare il compilatore. Se il chiamante del metodo Add non passa i tipi che funzionano con l’operatore +, il codice genererà un’eccezione in fase di runtime.

Le soluzioni fornite qui funzionano bene, ma ho pensato di aggiungerne un’altra che usi le espressioni

 public static T Add(T a, T b) { // Declare the parameters var paramA = Expression.Parameter(typeof(T), "a"); var paramB = Expression.Parameter(typeof(T), "b"); // Add the parameters together BinaryExpression body = Expression.Add(paramA, paramB); // Compile it Func add = Expression.Lambda>(body, paramA, paramB).Compile(); // Call it return add(a, b); } 

In questo modo stai creando un Func che esegue l’aggiunta. La spiegazione completa può essere trovata in questo articolo .

Il tipo T non è noto al compilatore, quindi non può trovare un operatore sovraccarico + definito ovunque …

Il meglio che puoi fare attualmente è dichiarare il tuo metodo come tale (poiché tutti i tipi numerici sono convertibili in double):

 public static double Add (double number1, double number2) { return number1 + number2; } 

o se sei sicuro che verrà definito un operatore + adatto:

 public static T Add(T number1, T number2) { dynamic dynamic1 = number1; dynamic dynamic2 = number2; return dynamic1 + dynamic2; } 

aggiornato

o una combinazione dei due:

 public static T Add(T in1, T in2) { var d1 = Convert.ToDouble(in1); var d2 = Convert.ToDouble(in2); return (T)(dynamic)(d1 + d2); } 

Questo è un problema che ho avuto quando volevo un metodo generico che potesse funzionare su liste arbitrarie di numeri, ad esempio:

 public T Calculate(IEnumerable numbers); 

La soluzione che ho trovato era usare un’espressione lambda:

 public T Calculate(Func add, IEnumerable numbers); 

Che poi chiameresti

 var sum = this.Calculate((a, b) => a + b, someListOfNumbers); 

Ovviamente in alcuni casi potresti anche avere + all’interno del codice invece delle espressioni lambda, ma se hai bisogno di eseguire operazioni matematiche in modo generico questa è stata la cosa più facile che ho potuto trovare che sia compilato in modo sicuro.

 Since this is generic type without a constraint compiler has no knowledge if the types involved will have '+' overloaded hence the compiler error These are some workarounds public static TResult Add(T1 left, T2 right, Func AddMethod) { return AddMethod(left, right); } var finalLabel = Add("something", 3,(a,b) => a + b.ToString()); Below code could let you build same but evaluated at run time so not run time safe public static T AddExpression(T left, T right) { ParameterExpression leftOperand = Expression.Parameter(typeof(T), "left"); ParameterExpression rightOperand = Expression.Parameter(typeof(T), "right"); BinaryExpression body = Expression.Add(leftOperand, rightOperand); Expression> adder = Expression.Lambda>( body, leftOperand, rightOperand); Func theDelegate = adder.Compile(); return theDelegate(left, right); } 
  public class generic { T result; public generic(T eval1, T eval2) { dynamic a = eval1; dynamic b = eval2; result = a + b; Console.WriteLine(result); Console.ReadLine(); } 

  static void Main(string[] args) { generic genobj = new generic(20,30); } 

Ciò impedisce agli sviluppatori di scrivere codice buggato. Poche domande per spiegare meglio la domanda:

1> Il compilatore conosce il tipo [No, perché è un tipo generico]. 2> Può accettare oggetti come parametro [Sì, può e per questo non saprà cosa fare con loro -> codice buggy]

Dato che vuoi impedire che il tuo codice sia bacato, C # non ti permette di avere ‘+’ ‘-‘ e altri operatori.

Soluzione: puoi usare il tipo “dinamico”, “var” e puoi restituirne la sum, se necessario.

Perché nessuno ha risposto fornendo una soluzione usando l’object. Pertanto sto aggiungendo la mia soluzione. In questo devi trasmettere i tuoi valori generici all’object.

Quindi questo è il codice funzionante:

 public static T Add(T number1, T number2) { object a = number1; object b = number2; return (T)(object)((int)a * (int)b).ToString(); } 

Prova questo codice. Questo è un codice generico per l’aggiunta.

 public static dynamic AddAllType(dynamic x, dynamic y) { return x + y; } 

Come si vede dal messaggio di errore, l’operatore ‘+’ non può essere applicato. Ciò si verifica perché il compilatore non sa nulla del tipo T. Non sa nemmeno che si tratta di una class o no.