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.