有人可以解释为什么这不起作用?无论数字类型如何,我都试图能够添加两个值.
public static T Add<T> (T number1, T number2)
{
return number1 + number2;
}
Run Code Online (Sandbox Code Playgroud)
当我编译它时,我收到以下错误:
Operator '+' cannot be applied to operands of type 'T' and 'T'
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 64
没有允许您强制运算符重载的通用约束.您可以查看以下库.或者,如果您使用的是.NET 4.0,则可以使用以下dynamic关键字:
public static T Add<T>(T number1, T number2)
{
dynamic a = number1;
dynamic b = number2;
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
显然,这不适用于任何编译时安全性,这是泛型的意思.应用编译时安全性的唯一方法是强制执行通用约束.对于您的场景,没有可用的约束.这只是欺骗编译器的技巧.如果Add方法的调用者没有传递与+运算符一起使用的类型,则代码将在运行时抛出异常.
Adi*_*ter 28
这里给出的解决方案运行良好,但我想我会添加另一个使用表达式的解决方案
public static T Add<T>(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<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
// Call it
return add(a, b);
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以创建一个Func<T, T, T>执行添加的方法.完整的解释可以在本文中找到.
Ric*_*lly 11
编译器不知道类型T,因此找不到任何地方定义的重载+运算符...
您当前可以做的最好的方法是声明您的方法(因为所有数字类型都可以转换为double):
public static double Add (double number1, double number2)
{
return number1 + number2;
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您确定将定义合适的+运算符:
public static T Add<T>(T number1, T number2)
{
dynamic dynamic1 = number1;
dynamic dynamic2 = number2;
return dynamic1 + dynamic2;
}
Run Code Online (Sandbox Code Playgroud)
更新
或两者的组合:
public static T Add<T>(T in1, T in2)
{
var d1 = Convert.ToDouble(in1);
var d2 = Convert.ToDouble(in2);
return (T)(dynamic)(d1 + d2);
}
Run Code Online (Sandbox Code Playgroud)
当我想要一个可以在任意数字列表上工作的泛型方法时,我就遇到了这个问题,例如:
public T Calculate<T>(IEnumerable<T> numbers);
Run Code Online (Sandbox Code Playgroud)
我发现的解决方案是使用lambda表达式:
public T Calculate<T>(Func<T, T, T> add, IEnumerable<T> numbers);
Run Code Online (Sandbox Code Playgroud)
然后你打电话给谁
var sum = this.Calculate((a, b) => a + b, someListOfNumbers);
Run Code Online (Sandbox Code Playgroud)
显然在某些情况下,您可能只是在代码中使用+而不是lambda表达式,但如果您需要以通用方式执行数学运算,这是我能想到的最简单的事情,即编译安全.
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, T2, TResult>(T1 left, T2 right, Func<T1, T2, TResult> 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>(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<Func<T, T, T>> adder = Expression.Lambda<Func<T, T, T>>(
body, leftOperand, rightOperand);
Func<T, T, T> theDelegate = adder.Compile();
return theDelegate(left, right);
}
Run Code Online (Sandbox Code Playgroud)