.NET delegate equality?

不羁的心 提交于 2019-12-07 01:34:26

Are you creating the delegate out of anonymous functions or something? These are the exact delegate equality rules according to C# specification (§7.9.8):

Delegate equality operators

Two delegate instances are considered equal as follows: If either of the delegate instances is null, they are equal if and only if both are null.
If the delegates have different runtime type they are never equal. If both of the delegate instances have an invocation list (§15.1), those instances are equal if and only if their invocation lists are the same length, and each entry in one’s invocation list is equal (as defined below) to the corresponding entry, in order, in the other’s invocation list. The following rules govern the equality of invocation list entries:
If two invocation list entries both refer to the same static method then the entries are equal.
If two invocation list entries both refer to the same non-static method on the same target object (as defined by the reference equality operators) then the entries are equal.
Invocation list entries produced from evaluation of semantically identical anonymous-function-expressions with the same (possibly empty) set of captured outer variable instances are permitted (but not required) to be equal.

So, in your case, it's possible that the delegate instances are referring to the same method in two different objects, or referring to two anonymous methods.


UPDATE: Indeed, the problem is that you are not passing the same method reference when you are calling new RelayCommand(param => OnCloseCommand()). After all, the lambda expression specified here is actually an anonymous method (you are not passing a method reference to OnCloseCommand; you are passing a reference to an anonymous method which takes a single parameter and calls OnCloseCommand). As mentioned in the last line of the specification quotation above, it's not necessary that comparing those two delegates return true.

Side Note: The getter of the CloseCommand property would be simply called get_CloseCommand and not <get_CloseCommand>b__0. This is the compiler generated method name for the anonymous method inside get_CloseCommand method (the CloseCommand getter). This further proves the point I mentioned above.

Ilya Khaprov

I don't know anything now about other lines but what if

CollectionAssert.AreEqual(_vm.ProjectActivities, models);

fails just because ReferenceEquality is used?

You have overridden the comparison for RelayCommand but not for ObservableCollection.

And it looks like in case of Delegates Reference equality is used too.

Try to compare by Delegate.Method instead.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!