代码之家  ›  专栏  ›  技术社区  ›  TerrorAustralis

定义实现+运算符[duplicate]的泛型

  •  8
  • TerrorAustralis  · 技术社区  · 14 年前


    Solution for overloaded operator constraint in .NET generics

    我有一个问题,我的工作,目前正在为它工作 int 但是我希望它适用于所有可以使用 + 接线员。有没有办法在泛型中定义这一点?例如,

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

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

    最终解决方案:

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

    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接口的依赖注入实例。输出类型通常是双精度的,因为操作的本质是数学的。

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

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

    好好享受!

    2 回复  |  直到 7 年前
        1
  •  9
  •   Timwi    14 年前

    这是C#的一个非常常见的新特性:能够指定比我们已有的更通用的参数约束。操作员是最常被问到的问题之一。但是,C目前并不支持这一点。

    可能的解决方法:

    • 这是最安全的类型选择,但是如果您需要经常调用这样的方法,那么它当然会很烦人。例如:

      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);
      
    • 声明自己的接口 IAddable int 作为参数。你必须使用 struct 内景 哪种工具 :

      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 . 另一种可能的解决方法是使用 ,但这是相当黑客和完全不安全的:它将允许您传入任何类型并调用任何方法或运算符,并且只在运行时崩溃,而不是在编译时崩溃。

        2
  •  2
  •   Bart    14 年前

    在C#4.0中是new关键字 动态 比尔。