如果“== 运算符未定义”会发生什么?
如果“== 运算符未定义”会发生什么?
示例:
class a
{
int variable = 0;
}
class b
{
void proc()
{
a ref1 = new a();
a ref2 = new a();
bool cmp1 = ref1 == ref2;//?
bool cmp2 = ref1 == ref1;//?
}
}
使用结构时有什么不同吗?
封送 (System.Runtime.Remoting.*
) 对象(单例)怎么样?
What happens if "== operator is not defined"?
Example:
class a
{
int variable = 0;
}
class b
{
void proc()
{
a ref1 = new a();
a ref2 = new a();
bool cmp1 = ref1 == ref2;//?
bool cmp2 = ref1 == ref1;//?
}
}
Does it differ when working with structs?
How about marshaled (System.Runtime.Remoting.*
) objects (singletons)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于用户定义的值类型,您的代码将无法编译。
具体来说,它会因以下错误而编译失败:“运算符 '==' 无法应用于类型 'a' 和 'a' 的操作数”。
"== 和 != 运算符无法对结构进行操作,除非该结构显式重载它们。"
您必须重载两者。您很可能不想在您的方法中使用默认的
Equals()
,因为“...对于结构,Object.Equals(Object)(这是 System.ValueType 中的重写版本)的默认实现通过使用反射来比较类型中每个字段的值来执行值相等检查。当实现者重写结构中的虚拟 Equals 方法时,目的是提供一种更有效的方法来执行值相等检查,并可选择将比较基于结构的字段或属性的某些子集。”
对于用户定义的引用类型(简化的情况,如OP的示例):
“即使类没有重载 == 和 != 运算符,但默认行为是在类中执行引用相等性检查。应该重载 == 和 != 运算符,但这不是必需的。”
如果不重载运算符,则很可能只有引用相等测试。
“简化的情况”,因为运算符重载解析可能会选择其他实现而不是默认。
单例在引用类型的上下文中最有意义,它们的目的是返回一个特定的实例。我无法想象引用相同但对象不“等于”自身的合理情况。
即使使用远程处理,最佳实践也是将操作合同与数据合同分开。
前者通常由服务器端的
MarshalByRefObject
实现 - 实现由接口定义的操作 - 而后者则使用按值编组并可能由客户端和服务器共享的数据/消息类。如果您重载数据类中的运算符,这可能不是一个大问题。然而,我相信这些不应该引用/调用远程对象。即使您提供了一个使运算符重载的自定义客户端代理,恕我直言,将远程调用隐藏在
==
和!=
运算符后面也是一种非常糟糕的做法,也是调试的噩梦。(如果我理解你的意图,我不确定。)
For user defined value types, your code won't compile.
Specifically, it would fail compilation with the following error: "Operator '==' cannot be applied to operands of type 'a' and 'a' ".
"The == and != operators cannot operate on a struct unless the struct explicitly overloads them."
You have to overload both of them. You most probably do not want to utilize the default
Equals()
in your method, since"...for structs, the default implementation of Object.Equals(Object) (which is the overridden version in System.ValueType) performs a value equality check by using reflection to compare the values of every field in the type. When an implementer overrides the virtual Equals method in a stuct, the purpose is to provide a more efficient means of performing the value equality check and optionally to base the comparison on some subset of the struct's field or properties."
For user defined reference types (simplified case, as in the OP's example):
"The == and != operators can be used with classes even if the class does not overload them. However, the default behavior is to perform a reference equality check. In a class, if you overload the Equals method, you should overload the == and != operators, but it is not required."
If you do not overload the operators, there will most probably only be a reference equality test.
"Simplified case", because operator overload resolution might select another implementation instead of the default.
Singletons are most meaningful in the context of reference types and their purpose is to return one specific instance. I cannot imagine a reasonable case where the reference is the same but the object is not "equal" to itself.
Even with remoting it is best practice to separate operation contracts from data contracts.
The former will typically be implemented by
MarshalByRefObject
s on the server side - implementing operations defined by interfaces - while the latter with data/message classes that are marshaled by value and might be shared by the client and server. It might not be a big problem if you overload the operators in data classes. These, however should not reference/make calls to remote objects, I believe.Even if you provide a custom client proxy that overloads the operators, imho it is a really bad practice and a debugging nightmare to hide remoting calls behind
==
and!=
operators.(If I understand your intentions, that I am not sure of.)
它可能会比较指针“a”和“b”,看它们是否指向内存中的同一对象。
如果您需要比较这些对象的字段,则必须定义比较器函数。
您需要继承 IComparable 接口并定义 CompareTo 方法。
看这里:IComparable 接口
It will likely compare pointers 'a' and 'b', whether they point to the same object in memory.
If you need to compare fields of those objects, you'll have to define the comparer function.
You'll need to inherit from IComparable interface and define the CompareTo method.
Look here: IComparable Interface
当 == 没有被重写时,我相信它会比较引用,检查它们是否是同一个对象。
示例:
因此,在上面的代码中,cmp1 将为 false,但 cmp2 将为 true
对于用户定义的值类型,但是,它会比较该类型的实际值。
When == is not overridden, I believe it compares references, checking if they are the same object.
Example:
So therefore, in your code above, cmp1 would be false, but cmp2 would be true
For user defined value types, however, it compares the actual value of the type.
来自 MSDN:
From MSDN: