C# 将以相同的方式处理这些代码(具有基类约束的泛型类与非泛型类“对应”的类)

C# 将以相同的方式处理这些代码(具有基类约束的泛型类与非泛型类“对应”的类),c#,generics,interface,implementation,C#,Generics,Interface,Implementation,我正在为我的类清单测试IComparer接口的实现。我有两个版本的it实现,它的工作原理相同吗?(问题1) 类目录 { 公共字符串名称; 双重成本; 现有国际贸易; 公共资源清册(字符串n,双c,整数h) { //... } } } 类CustomInvComparer:IComparer { 公共整数比较(库存x、库存y) { 返回string.Compare(x.name,y.name,StringComparison.Ordinal); } } 类别CompInv:i比较者,其中T:

我正在为我的类清单测试IComparer接口的实现。我有两个版本的it实现,它的工作原理相同吗?(问题1)

类目录
{
公共字符串名称;
双重成本;
现有国际贸易;
公共资源清册(字符串n,双c,整数h)
{ //...    }
}
}
类CustomInvComparer:IComparer
{
公共整数比较(库存x、库存y)
{
返回string.Compare(x.name,y.name,StringComparison.Ordinal);
}
}
类别CompInv:i比较者,其中T:Inventory
{
公共整数比较(TX,TY)
{
返回string.Compare(x.name,y.name,StringComparison.Ordinal);
}
}
在实现int32和string的IComparer接口时,为什么“第二个变量”不起作用(w/o注释将是主要错误CS0701)我知道从语法“类型参数约束(C#编程指南)”的角度来看,“第二个变量”(注释)是不正确的,但我没有看到与前面的变量“where t:Inventory”的逻辑区别?(问题2)

类CustomStringComparer:IComparer
{
公共整数比较(System.String x,System.String y)
{
返回x.CompareTo(y);
}
}
//类CompStr:IComparer,其中T:System.String
//{
//公共整数比较(TX,TY)
//    {
//返回string.Compare(x,y,StringComparison.Ordinal);
//    }
//}
类CustomIntComparer:IComparer
{
公共整数比较(System.Int32 x,System.Int32 y)
{
返回x.CompareTo(y);
}
}
//类CompStr:i比较程序,其中T:System.Int32
//    {
//公共整数比较(TX,TY)
//    {
//返回string.Compare(x,y,StringComparison.Ordinal);
//    }
//}
我有两个版本的it实现,它的工作原理是否相同?(问题1)

您的两个
IComparer
实现具有完全相同的逻辑,因此从这个意义上讲,它们的工作原理完全相同。唯一的重要区别是,通用版本不仅可以比较
库存
的类型,还可以比较
库存
的任何子类

由于通过泛型接口中的类型参数差异,您可以在使用
Inventory
子类的场景中使用非泛型版本,因此这种差异没有太多实际意义。您应该能够在完全相同的情况下使用这两种方法

至于你的第二个问题:

在实现int32和string的IComparer接口时,为什么“第二个变量”不起作用(没有注释将是主要错误CS0701)

答案就在:

用作约束的类型必须是接口、非密封类或类型参数

System.String
是一个密封类,
System.Int32
根本不是类。它们都不是接口或类型参数。因此,两者都不符合约束条件

更实际地说:密封类和值类型(结构,即类似于
System.Int32
)不是有效约束的原因是它们作为约束没有任何意义。约束允许类型参数是继承约束类型的类型。但是密封类和值类型不能具有继承的类型。因此,使用它们作为约束将不会带来任何好处。在这种情况下,最好省略类型参数并显式使用该类型

我有两个版本的it实现,它的工作原理是否相同?(问题1)

您的两个
IComparer
实现具有完全相同的逻辑,因此从这个意义上讲,它们的工作原理完全相同。唯一的重要区别是,通用版本不仅可以比较
库存
的类型,还可以比较
库存
的任何子类

由于通过泛型接口中的类型参数差异,您可以在使用
Inventory
子类的场景中使用非泛型版本,因此这种差异没有太多实际意义。您应该能够在完全相同的情况下使用这两种方法

至于你的第二个问题:

在实现int32和string的IComparer接口时,为什么“第二个变量”不起作用(没有注释将是主要错误CS0701)

答案就在:

用作约束的类型必须是接口、非密封类或类型参数

System.String
是一个密封类,
System.Int32
根本不是类。它们都不是接口或类型参数。因此,两者都不符合约束条件


更实际地说:密封类和值类型(结构,即类似于
System.Int32
)不是有效约束的原因是它们作为约束没有任何意义。约束允许类型参数是继承约束类型的类型。但是密封类和值类型不能具有继承的类型。因此,使用它们作为约束将不会带来任何好处。在这种情况下,最好省略type参数并显式使用该类型。

看看我之前写的“第二个变体”(注释)从语法角度看是不正确的”。我的问题是——为什么这样做?另外,给出“where T:struct”的是什么,请一次问一个问题。还请确保你问的每个问题都是清楚的。@PeterDuniho好的,我简化了-我删除了其他问题。两个问题相互关联。可以吗?看看我之前写的“第二个变体”(注释)从语法角度来看是不正确的”。我的问题是——为什么我
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);
        }
    }
    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);
//    }
//}