Linq Where无法识别自定义对象的运算符重载

Linq Where无法识别自定义对象的运算符重载,linq,.net-3.5,Linq,.net 3.5,我有一个私有类User,它实现了一个接口IQMUser,带有 public static bool operator ==( User a, User b ) { return Equals( a, b ); } public static bool operator !=( User a, User b ) { return !Equals( a, b ); } public override bool Equals ( object obj ) {

我有一个私有类User,它实现了一个接口IQMUser,带有

    public static bool operator ==( User a, User b ) { return Equals( a, b ); }
    public static bool operator !=( User a, User b ) { return !Equals( a, b ); }
    public override bool Equals ( object obj )
    {
        User other = obj as User;
        return m_LMUser.UserID == other.m_LMUser.UserID;
    }
    public override int GetHashCode ( )
    {
        return m_LMUser.GetHashCode ( );
    }
User是公共类UserManager的成员,该类具有GetUsers(),返回
IList
。在另一节课上,我有

    IQMUser otherUser = UserManager.GetUsers( )
        .Where( u => u != CurrentUser )
        .FirstOrDefault( ); 
现在,我知道了一个事实,GetUsers返回的对象与CurrentUser具有相同的m_LMUser.UserID。然而,测试u!=即使在这种情况下,CurrentUser也始终为true

我在User中的每个操作符重载和Equals重写上都设置了断点,但没有一个断点命中

然后我将查询更改为

    IQMUser otherUser = UserManager.GetUsers( )
        .Where( u => !u.Equals( CurrentUser ) )
        .FirstOrDefault( ); 
这将按预期命中重写的Equals方法


我的运算符重载有什么问题,Linq甚至没有命中它们?

从外观上看,您的==实现调用的是静态对象.Equals方法,而不是实例Equals方法。这将检查两个引用是否指向同一块内存()

将其更改为:

public static bool operator ==( User a, User b ) { return a.Equals(b); }
public static bool operator !=( User a, User b ) { return !a.Equals(b); }
您还应将equals方法更改为:

public override bool Equals ( object obj )
{
    User other = obj as User;
    return !Object.ReferenceEquals(other, null) && m_LMUser.UserID == other.m_LMUser.UserID;
}

如果我正确理解了继承层次结构,“Where”中的类型似乎是
IQMUser
(基类),而
操作符==
是在子类
User
上实现的

由于
操作符==
非虚拟的,因此类型为
IQMUser
的Linq Where表达式将运行
IQMUser操作符==
,而不是在
用户
上实现的操作符


另一方面,Equals是虚拟的,重写工作正常,如果您直接调用它,它可以正常工作。

什么类型的
UserManager.GetUsers()
?这就解释了-如果您尝试使用任何类型的变量
IQMUser
。Uhhh stack overflow;-),您会看到完全相同的结果“other!=null”将调用运算符==该运算符已多次击中我。stackoverflow会在没有警告的情况下终止web服务器进程。尽管重载运算符的实现可能有问题,但问题仍然是它们甚至没有被调用。我编辑了原始问题,以澄清IQMUser是一个接口,而不是基类。因此,我不能为IQMUser指定运算符==重载。@KellyLine如果IQMUser是一个接口,那么在您的情况下,您很可能必须满足于
等于
,因为您无法在其上实现正确的静态
运算符==
,并且因为它是静态运算符,所以它不能是虚拟的。您可以将IQMUser变成一个抽象基类,在这个基类中,
操作符==
调用虚拟的
Equals
,但是不必键入
Equals
,这似乎是一项非常艰巨的工作。谢谢。只要我明白为什么我必须这么做,我不介意接受平等。