定义实现+运算符的通用

可能重复:
.NETgenerics中重载运算符约束的解决方案

我有一个问题,我正在努力,目前它正在为int工作,但我希望它适用于所有可以使用+运算符添加的类。 有没有办法在通用中定义它? 例如,

 public List Foo() where T : ISummable 

有没有办法做到这一点?

编辑:
传入委托进行求和而不是使用+ =类型为Int的性能最好慢540%。 调查可能的其他解决方案

最终解决方案
谢谢大家的建议。 我最终找到了一个不太慢的解决方案,并在编译时强制执行检查。 当一位同事帮我解决这个问题时,我无法完全信任。 无论如何,这里是:

以函数的forms实现一个包含所有必需操作符的接口

 public interface IFoo { //Adds A to B and returns a value of type OutputType OutputType Add(InputType a, InputType b); //Subtracts A from B and returns a value of type OutputType OutputType Subtract(InputType a, InputType b); } 

创建要定义的类,但不使用Where子句,而是使用IFoo接口的依赖项注入实例。 OutputType通常是双倍的,因为操作的性质是数学的。

 public class Bar { private readonly IFoo _operators; public Bar(IFoo operators) { _operators = operators; } } 

现在,当您使用此类时,您可以像这样定义操作规则:

 private class Foo : IFoo { public double Add(int a, int b) { return (double)(a+b); } public double Subtract(int a, int b) { return (double)(ab); } } 

然后你会像这样使用它:

 Foo inttoDoubleOperations = new Foo(); Bar myClass = new Bar(Foo); 

这样所有操作都在编译时强制执行:)

请享用!

这是C#非常常见的新function:能够指定比我们已有的更通用的参数约束。 运营商是最常被问到的。 但是,C#目前不支持此function。

可能的解决方法:

  • 将委托传递给任何需要添加的方法。 这是最类型安全的选项,但是如果你需要经常调用这样的方法,那当然很烦人。 例如:

     public class Generic { public void DoSomething(T anItem, T anotherItem, Func add) { // instead of Blah(anItem + anotherItem); // have to write: Blah(add(anItem, anotherItem)); } } Generic genInt = ...; // and then instead of ... genInt.DoSomething(1, 2); // have to write: genInt.DoSomething(1, 2, (a, b) => a + b); 
  • 声明自己的接口IAddable 然后你可以将它用作generics类型参数约束,但显然你不能使用int作为参数。 您必须使用自己的structIAddable包含一个int并实现IAddable

     public interface IAddable { T Add(T other); } public struct Integer : IAddable { public int Value; public Integer(int value) { Value = value; } public Integer Add(Integer other) { return new Integer(Value + other.Value); } } // then instead of Generic blah = ...; // have to write: Generic blah = ...; 
  • dynamic 另一种可能的解决方法是使用dynamic ,但这是相当hacky并且完全不安全:它将允许您传入任何类型并调用任何方法或操作符,并且只在运行时崩溃,而不是在编译时崩溃。

在C#4.0中是新的关键字动态 ,允许您在运行时执行此操作。 在以前的版本中它可能但对我来说太阴暗和棘手。 但是你可以总是传递一个代理,它将在generics中执行添加。 否则它是不可能的,因为没有ISummable,IAdditive,一般来说,没有办法知道在编译时是什么是加法*。 如果您希望得到进一步的评论,我会在以后添加。 BR。

  • 我的意思是,除了让你拥有IAdditive并用它们标记某些类型,但它不会用例如int。