C#添加两个通用值

有人可以解释为什么这不起作用吗? 我试图能够添加两个值,无论数字types。

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

当我编译这个,我得到以下错误:

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

10 Solutions collect form web for “C#添加两个通用值”

没有通用的约束,允许您强制执行运算符重载。 你可以看看下面的库 。 另外,如果您使用.NET 4.0,则可以使用dynamic关键字:

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

显然,这不适用于generics所要求的编译时安全性。 应用编译时安全的唯一方法是强制通用约束。 而对于你的情况,没有可用的限制。 欺骗编译器只是一个骗术。 如果Add方法的调用方不传递与+运算符一起工作的types,则代码将在运行时抛出exception。

这里给出的解决scheme运作良好,但我想我会添加另一个使用expression式

 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); } 

这样你就创build了一个执行加法的Func<T, T, T> 。 完整的解释可以在这篇文章中find。

typesT不是编译器已知的,所以它找不到在任何地方定义的重载+运算符…

你现在可以做的最好的是声明你的方法(因为所有的数字types都可以转换为double):

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

或者如果你确定一个合适的+操作符将被定义:

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

更新

或两者的组合:

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

当我想要一个可以在任意数字列表上工作的generics方法时,这是一个问题,例如:

 public T Calculate<T>(IEnumerable<T> numbers); 

我find的解决scheme是使用lambdaexpression式:

 public T Calculate<T>(Func<T, T, T> add, IEnumerable<T> numbers); 

然后你会打电话给你

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

很显然,在某些情况下,你可能只是在代码里面加上+而不是lambdaexpression式,但是如果你需要用通用的方式来执行math运算,这是我能想到的最简单的事情,那就是编译安全。

 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); } 
  public class generic<T> { 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<int> genobj = new generic<int>(20,30); } 

这可以防止开发人员编写错误的代码。 很less有问题可以更好地解释这个问题:

1>编译器是否知道types[不,因为它是genericstypes]。 2>它可以接受对象作为参数[是的,它可以,因此它不会知道如何处理它们 – >多function代码]

既然,你想防止你的代码变成bug,C#不允许你有'+'''和其他操作符。

解决scheme:如果需要,可以使用“dynamic”,“var”types并返回它们的总和。

因为没有人使用对象提供解决scheme来回答 因此我正在添加我的解决scheme。 在这个你必须把你的通用值的对象。

所以这是工作代码:

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

试试这个代码。 这是添加的通用代码。

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

正如您从错误消息中看到的那样,运算符“+”不能被应用。 这是因为编译器对Ttypes一无所知。 甚至不知道这是否是一堂课。

  • ArrayList vs List <> in C#
  • 通用types检查
  • Java通用类 - 确定types
  • JavagenericsT vs Object
  • 我如何使用接口作为C#genericstypes约束?
  • 为什么我不能使用float值作为模板参数?
  • Javagenerics强制执行兼容通配符
  • 什么是物化?
  • 如何将DataTable转换为通用列表?
  • 如何找出每个对象在ArrayList <Object>中的types?
  • recursiongenericstypes的实例化在它们嵌套的越深处指数地减慢。 为什么?