【问题标题】:Should overloaded methods with value types be consolidated into a generic method?是否应该将具有值类型的重载方法合并为泛型方法?
【发布时间】:2009-12-31 21:14:48
【问题描述】:

在执行 OO 设计时,将使用简单值类型的方法集合合并到一个泛型方法中会更好吗?例如:

public int Sum(int x, int y)

// Overload with float.
public float Sum(float x, float y)

合并到:

public T Sum<T> (T x, T y)

谢谢,

斯科特

【问题讨论】:

    标签: c# generics oop


    【解决方案1】:

    通常是的,但是,特别是对于您的示例(将两个参数相加)-您不能使用泛型来做到这一点,因为 + 运算符不是您可以限制泛型类型参数的任何接口的一部分: )

    (注意:这是我的 C# 部分,用其他语言可能仍然可行)

    【讨论】:

    • 感谢您的回答!是不可能做到这一点,还是一个糟糕的设计决定?我正在考虑现在编写的方式,这两个参数都是不受约束的,因此有人可以传入任何对象,并且 + 操作不会对所有类型都重载,因此它会中断。这听起来对吗?
    • 是的,CLR 的一个缺失部分是一个接口INumeric,它将包括那些运算符,(适用于实现它们的所有核心类型 - int、uint、float、decimal 等。 )
    • @Scott Davies - 不,这是不可能的(读取 - 编译错误),编译器不知道如何将调用转换为无约束类型的“+”。如果类型不受约束,则任何方法都是如此,而不仅仅是“+”。
    • 不,它不会按原样工作,因为一旦你在这个泛型函数中使用 + 运算符,编译器就会抱怨,因为你没有限制 T 类型,它知道不是每个类型可以使用 + 运算符...
    • 啊,好的。那么,编译时错误是好的,因为它会阻止它。谢谢!
    【解决方案2】:

    某些情况下,是的(并非总是如此);尽管有相反的谣言,但这是可能的。我为"MiscUtil"(免费等)编写了一些代码,完全做到了这一点,并且适用于具有合适运算符的所有类型(甚至是您自己的结构和类,或Nullable&lt;T&gt; 等)。

    这里的问题是没有支持Add 等的接口,所以在dynamic 出现之前(在4.0 中)这很棘手;但可以做到 - 这是usage page,带有简化版Sum(“MiscUtil”中的实际代码稍微复杂一些):

    public static T Sum<T>(this IEnumerable<T> source)
    {
        T sum = Operator<T>.Zero;
        foreach (T value in source)
        {
            if (value != null)
            {
                sum = Operator.Add(sum, value);
            }
        }
        return sum;
    }
    

    再一次,在 4.0 中,dynamic 中的很多内容相对简单,因为它支持运算符;但是,上次我对其进行基准测试时,dynamic 比我(ab)使用 Expression 慢。

    顺便说一句,标准 LINQ 可以提供Min / Max 的原因是因为IComparable/IComparable&lt;T&gt;Comparer&lt;T&gt;.Default 的协助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2018-08-28
      相关资源
      最近更新 更多