如何使用泛型来实现这个?

时间:2017-02-14 08:54:50

标签: c# generics

  

泛型用于将逻辑与数据类型分离。

public class Calc<T>
{
   public T Add(T a, T b)
   {
       return (a+b);
   }
}

但是这会抛出以下编译时错误

操作员+无法应用于T类型。

我不明白为什么会这样。因为如果它允许来自main.cs

main()
{
     Calc<int> obj = new Calc<int>();
     int c = obj.Add(10,20);
}

有人可以解释为什么我会收到Build错误吗?

4 个答案:

答案 0 :(得分:2)

C#泛型不支持任意运算符。必须在泛型类型的编译时中知道确切的(可能是虚拟的)方法。由于示例中的泛型类型参数根本不受约束,因此您只能使用object类型的成员,该成员不包含+运算符。

没有办法使用C#generics来做你想做的事,抱歉。您可以做的最好的事情是对一些已知类型的一系列类型检查(以及适当的强制转换,对于值类型来说很棘手),或者使用反射(dynamic特别适用)。

答案 1 :(得分:1)

Calc<T>这样的不受限制的泛型必须能够使用任何类型进行编译,并非所有类型都支持+操作数,因此您的代码无法编译。这与您使用。

创建调用代码的具体类型无关

您可以限制T的类型,从而通过Calc<T> where T:objectCalc<T> where T: IComparable访问更多方法,这样您就可以:

public T CompareTo(T a, T b)
{
   return (a.CompareTo(b));
}

由于所有T现在必须实施IComparable。遗憾的是,Int32未实现任何定义+运算符或任何添加方法的接口。所以没有办法实现你正在尝试的那个陈述。

答案 2 :(得分:0)

C#泛型与C ++模板不同。如果泛型类型没有使用used方法的定义(在你的情况下是operator +),则无法编译C#代码,而C ++编译器将此方法应用于实际的模板参数类型。

答案 3 :(得分:0)

不允许添加,因为无法保证传递的类型具有operator + overload 有一种方法可以实现,但只要您传递具有operator +的类型,它就会起作用。否则,将抛出RuntimeBinderException。此外,对性能有一些影响,但除非代码对性能至关重要,否则不应该成为问题。

public T Add<T>(T a, T b)
{
  dynamic da = a, db = b;
  return da + db;
}