.net 为什么我不能比较某个隐式类型的两个泛型对象?

.net 为什么我不能比较某个隐式类型的两个泛型对象?,.net,generics,.net,Generics,考虑以下代码: public class SystemManager<T> where T : ISettings { public SystemManager() { T implicit1 = default(T); T implicit2 = default(T); if (implicit1 != implicit2) { // This will not compile

考虑以下代码:

public class SystemManager<T> where T : ISettings
{
    public SystemManager()
    {
        T implicit1 = default(T);
        T implicit2 = default(T);
        if (implicit1 != implicit2)
        {
            // This will not compile saying the compiler cannot compare
            // using '!=' two objects of type 'T' and 'T'
        }

        ISettings explicit1 = null;
        ISettings explicit2 = null;
        if (explicit1 != explicit2)
        {
            // This will compile fine
        }
    }
}
我可以执行上述操作,并实现SystemManager的通用,
StructSettings
版本:

然后,在SystemManager中,我可以比较这两个结构,而不会出现运行时错误

SystemManager<StructSettings> manager = new SystemManager<StructSettings>();
SystemManager=newsystemmanager();

这是可行的,SystemManager的构造函数中的结构上的==不会引发任何运行时错误。

有趣的是:我认为这与编译器不知道T是引用还是值类型有关,因为如果添加约束T:class,它的编译就可以了


比较的语义是比较引用是否相等。

有趣的是:我认为这与编译器不知道T是引用还是值类型有关,因为如果添加约束T:class,它编译得很好


比较的语义是比较引用是否相等。

显然,运算符==未在结构中实现。这就是为什么如果你把T:类,它会工作



该文件的链接可以让我们看到您所说的正在运行的版本,这将非常好:)。或者只是编辑您的帖子。

显然,运算符==没有在结构中实现。这就是为什么如果你把T:类,它会工作




该文件的链接可以让我们看到您所说的正在运行的版本,这将非常好:)。或者直接编辑你的帖子。

我没有答案,但你为什么需要使用泛型,而你可以直接使用类型设置?@Manu-我已经用你的问题的答案更新了我的问题。我没有答案,但你为什么需要使用泛型,当您可以直接使用类型ISettings时?@Manu-我已经用您的问题的答案更新了我的问题,但是我在显式示例中对ISettings的实现可以是一个结构,这正是让我困惑的地方。那么你需要ISettings来实现IEquatable,因为在结构上没有默认值==。@sirrocco-我已经用关于你的回答的一点更新了我的问题。如果你使用的是第二个版本“ISettings explicit1=null;”-那么explicit1是一个引用类型,这就是它工作的原因。只要实现IEquatable use.Equals并使用它:)@sirrocco-我可以让它正常工作-比较null,然后使用.Equals检查(否则.Equals显然会在null上失败)-但我想知道编译器的脑袋里发生了什么!:)但是我在显式示例中对ISettings的实现可能是一个结构,这让我很困惑。那么您需要ISettings来实现IEquatable,因为在结构上没有默认值==。@sirrocco-如果您使用的是第二个版本“ISettings explicit1=null;”,我已经更新了关于您的回答的问题-那么explicit1是一种引用类型,这就是它工作的原因。只要实现IEquatable use.Equals并使用它:)@sirrocco-我可以让它正常工作-比较null,然后使用.Equals检查(否则.Equals显然会在null上失败)-但我想知道编译器的脑袋里发生了什么!:)@活力-见我的更新答案(编辑2)。在显式版本中,它不知道ISettings是ref还是value类型,当然?我不确定您做了什么。。如果不设置类约束,则不会编译此内容。我不明白你是如何编译的?@Vitality-见我的最新答案(编辑2)。在显式版本中,它不知道ISettings是ref还是value类型,当然?我不确定您做了什么。。如果不设置类约束,则不会编译此内容。我不明白你是怎么编译的?
public struct StructSettings : ISettings
{

}
SystemManager<StructSettings> manager = new SystemManager<StructSettings>();