运算符=不能应用于C#中的泛型类型吗?

运算符=不能应用于C#中的泛型类型吗?

根据文件==运算符MSDN,

对于预定义的值类型,如果操作数的值相等,则相等运算符(=)返回true,否则为false。对于字符串以外的引用类型,如果其两个操作数引用同一个对象,则=返回true。对于字符串类型,=比较字符串的值。用户定义的值类型可以重载=操作符(请参阅操作符)。用户定义的引用类型也可以,尽管默认情况下,对于预定义和用户定义的引用类型,其行为都如上文所述。

那么,为什么这个代码段无法编译呢?

bool Compare<T>(T x, T y) { return x == y; }

我知道错误运算符‘=’不能应用于‘T’和‘T’类型的操作数..我不知道为什么,据我所知==操作符是否为所有类型预定义?

编辑:谢谢各位。一开始,我没有注意到这条语句只是关于引用类型的。我还认为,对所有值类型都提供了逐点比较,我现在知道的是对,是这样。

但是,如果我使用的是引用类型,==运算符使用预定义的引用比较,或者如果类型定义了,它会使用操作符的重载版本吗?

编辑2:经过反复试验,我们了解到==运算符在使用无限制泛型类型时将使用预定义的引用比较。实际上,编译器将对受限类型参数使用它能找到的最佳方法,但不会进一步研究。例如,下面的代码将始终打印true,即使当Test.test<B>(new B(), new B())称为:

class A { public static bool operator==(A x, A y) { return true; } }class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T b) where T : A { Console.WriteLine(a == b); } }


慕仙森
浏览 813回答 3
3回答

largeQ

“.在默认情况下,对于预定义和用户定义的引用类型,行为都如上文所述。”类型T不一定是引用类型,所以编译器不能这样做。但是,这将编译,因为它更显式:&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Compare<T>(T&nbsp;x,&nbsp;T&nbsp;y)&nbsp;where&nbsp;T&nbsp;:&nbsp;class &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;==&nbsp;y; &nbsp;&nbsp;&nbsp;&nbsp;}接着补充一个问题,“但是,如果我使用的是引用类型,那么=操作符是使用预定义的引用比较,还是使用重载版本的操作符(如果是类型定义的话)?”我原以为=on Generics会使用重载版本,但下面的测试说明的不是这样。有趣.。我很想知道为什么!如果有人知道,请分享。namespace&nbsp;TestProject{ &nbsp;class&nbsp;Program &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;Main(string[]&nbsp;args) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test&nbsp;a&nbsp;=&nbsp;new&nbsp;Test(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Test&nbsp;b&nbsp;=&nbsp;new&nbsp;Test(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine("Inline:"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;x&nbsp;=&nbsp;a&nbsp;==&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine("Generic:"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compare<Test>(a,&nbsp;b); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;bool&nbsp;Compare<T>(T&nbsp;x,&nbsp;T&nbsp;y)&nbsp;where&nbsp;T&nbsp;:&nbsp;class &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;==&nbsp;y; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;} &nbsp;class&nbsp;Test &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;bool&nbsp;operator&nbsp;==(Test&nbsp;a,&nbsp;Test&nbsp;b) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine("Overloaded&nbsp;==&nbsp;called"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a.Equals(b); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;bool&nbsp;operator&nbsp;!=(Test&nbsp;a,&nbsp;Test&nbsp;b) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine("Overloaded&nbsp;!=&nbsp;called"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a.Equals(b); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;}}输出量内联:重载=调用通用:按任意键继续。....后续行动2我想指出的是,将我的比较方法改为&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;bool&nbsp;Compare<T>(T&nbsp;x,&nbsp;T&nbsp;y)&nbsp;where&nbsp;T&nbsp;:&nbsp;Test &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;x&nbsp;==&nbsp;y; &nbsp;&nbsp;&nbsp;&nbsp;}导致调用重载=操作符。我想没有指定类型(作为哪里),编译器不能推断它应该使用重载运算符.尽管我认为它有足够的信息来做出这个决定,即使没有指定类型。

侃侃无极

正如其他人所说,只有当T被限制为引用类型时,它才会起作用。在没有任何约束的情况下,您可以使用NULL进行比较,但只能使用NULL进行比较,对于非空值类型,这种比较始终是假的。与其调用等于,不如使用IComparer<T>-如果你没有更多的信息EqualityComparer<T>.Default是个不错的选择:public&nbsp;bool&nbsp;Compare<T>(T&nbsp;x,&nbsp;T&nbsp;y){ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;EqualityComparer<T>.Default.Equals(x,&nbsp;y);}除了其他任何东西,这避免了拳击/铸造。

撒科打诨

总体而言,EqualityComparer<T>.Default.Equals应该用任何实现IEquatable<T>,或者说这是明智的Equals执行。但是,如果,==和Equals由于某种原因而实现不同,那么我的工作是泛型运算符应该是有用的;它支持操作者版本(除其他外):相等(T值1,T值2)不相等(T值1,T值2)大于(T值1,T值2)LessThan(T值1,T值2)(T值1,T值2)LessThanOrequue(T值1,T值2)
打开App,查看更多内容
随时随地看视频慕课网APP