c# - 定义一个实现 + 运算符的泛型

标签 c# generics operators

<分区>

Possible Duplicate:
Solution for overloaded operator constraint in .NET generics

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

public List<T> Foo<T>() where T : ISummable

有什么办法吗?

编辑:
传递一个委托(delegate)来进行求和而不是使用 += 和 Int 类型的性能最多慢 540%。研究可能的其他解决方案

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

以函数的形式实现一个接口(interface),其中包含所有必需的运算符

public interface IFoo<InputType, OutputType>
{
    //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 接口(interface)的依赖注入(inject)实例。 OutputType 通常是 double,因为操作的性质是数学的。

public class Bar<T>
{
    private readonly IFoo<T,double> _operators;

    public Bar(IFoo<T, double> operators)
    {
        _operators = operators;
    }
}

现在当你使用这个类时,你定义操作规则如下:

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

然后你会像这样使用它:

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

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

尽情享受吧!

最佳答案

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

可能的解决方法:

  • 将委托(delegate)传递给任何需要做加法的方法。这是最安全的选项,但如果您需要经常调用这样的方法,当然会很烦人。例如:

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

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

关于c# - 定义一个实现 + 运算符的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3598341/

相关文章:

c# - WPF 如何让 RichTextBox 的宽度跟随父控件的宽度?

c# - 切换到任何 CPU 配置后,Win Service 项目不会构建

c# - trace元素中的autoflush属性有什么作用

c# - Web应用中, "ressource cannot be found"异常时当前session为null

java - Java 8 中::运算符的名称是什么

java - 如何构建泛型类和构造函数以使用泛型方法?

generics - 将使用泛型的 Java 5 代码转换为可以在 J2ME 设备上运行的代码?

c# - 获取通用接口(interface)的所有实现类型

Scala - 使用 Bounds 理解类定义

javascript - 为什么 '+' 运算符要连接我的数字?