将使这些代码相同(具有基类约束的通用类与非通用类的“对等”)

时间:2019-03-26 23:41:50

标签: c# generics interface implementation

我正在为我的班级清单测试IComparer接口的实现。我有两个版本的实现,它会一样工作吗? (问题1)

class Inventory
{
    public string name;
    double cost;
    int onhand;
    public Inventory(string n, double c, int h)
    { //...    }
    }
}
class CustomInvComparer : IComparer<Inventory>
    {
        public int Compare(Inventory x, Inventory y)
        {
            return string.Compare(x.name, y.name, StringComparison.Ordinal);
        }
    }
class CompInv<T> : IComparer<T> where T : Inventory
    {
        public int Compare(T x, T y)
        {
            return string.Compare(x.name, y.name, StringComparison.Ordinal);
        }
    }

为什么在实现int32和string的IComparer接口的情况下,“第二个变体”不起作用(不带注释将是主要错误CS0701)。 我知道从语法“类型参数的约束(C#编程指南)”的角度来看,“第二个变体”(注释)是不正确的,但是与上述变体“ where T:库存”? (问题2)

    class CustomStringComparer : IComparer<System.String>
{
    public int Compare(System.String x, System.String y)
    {
        return x.CompareTo(y);
    }
}

//class CompStr<T> : IComparer<T> where T : System.String
//{
//    public int Compare(T x, T y)
//    {
//        return string.Compare(x, y, StringComparison.Ordinal);
//    }
//}

class CustomIntComparer : IComparer<System.Int32>
{
    public int Compare(System.Int32 x, System.Int32 y)
    {
        return x.CompareTo(y);
    }
}

//class CompStr<T> : IComparer<T> where T : System.Int32
//    {
//    public int Compare(T x, T y)
//    {
//        return string.Compare(x, y, StringComparison.Ordinal);
//    }
//}

1 个答案:

答案 0 :(得分:0)

  

我有两个版本的实现,它会一样工作吗? (问题1)

您的两个IComparer<T>实现具有完全相同的逻辑,因此从某种意义上讲,它们将完全相同。唯一的实质区别是通用版本不仅可以比较Inventory的类型,还可以比较Inventory的任何子类。

由于通过通用接口中的类型参数变化,您可以在使用Inventory子类的情况下使用非通用版本,因此这种区别没有太大的实际意义。您应该可以在完全相同的情况下使用。

关于您的第二个问题:

  

为什么在实现int32和字符串的IComparer接口的情况下,“第二个变体”不起作用(不带注释将是主要错误CS0701)

答案正确在the error message

  

用作约束的类型必须是接口,未密封的类或类型参数。

System.String是一个密封的类,而System.Int32根本不是一个类。这些都不是接口或类型参数。因此,都没有资格作为约束。

更实际地说:密封类和值类型(结构,例如System.Int32之类)不是有效约束的原因是,它们作为约束没有任何意义。约束允许type参数是继承约束类型的类型。但是密封的类和值类型不能具有继承的类型。因此,将它们用作约束将提供零收益。在这种情况下,您也可以省略type参数并显式使用该类型。