为什么运算符'=='不能应用于struct和default(struct)?

Dyl*_*tie 19 c# struct operators

在对结构集合使用FirstOrDefault()之后,我看到了一些奇怪的行为.我把它分成了这个复制案例.这个程序不会编译

using System;
using System.Linq;

namespace MyProgram {
    public class Program {
        static void Main() {

            var users = new User[] {
            new User() { UserGuid = Guid.NewGuid(), Username = "user01" },
            new User() { UserGuid = Guid.NewGuid(), Username = "user02" }
        };

            var user = users.FirstOrDefault(u => u.Username == "user01");
            Console.WriteLine(user == default(User) ? "not found" : "found");
        }

    }

    public struct User {
        public Guid UserGuid;
        public string Username;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器错误是相当神秘的:

运算符'=='不能应用于'MyProgram.User'和'MyProgram.User'类型的操作数

将结构更改为类可以正常工作 - 但我不知道为什么我无法将结构'实例'与默认值进行比较?

Cya*_*ish 23

对于类,==运算符使用引用相等性.当然,结构是值类型,因此无法通过引用进行比较.==结构没有默认实现,因为成员比较并不总是有效的比较,具体取决于类型.

您可以改为使用Object.Equals比较成员的方法:

Console.WriteLine(user.Equals(default(User)) ? "not found" : "found");
Run Code Online (Sandbox Code Playgroud)

或者你可以实现==调用Object.Equals:

public static bool operator ==(User lhs, User rhs)
{
    return lhs.Equals(rhs);
}
Run Code Online (Sandbox Code Playgroud)

但是,结构的默认实现Equals使用反射,因此非常慢.这将是更好地执行Equals自己,连同==!=(也可能是GetHashCode太):

public override bool Equals(Object obj)
{
    return obj is User && Equals((User)obj);
}

public bool Equals(User other)
{
    return UserGuid == other.UserGuid && Username == other.Username;
}

public static bool operator ==(User lhs, User rhs)
{
    return lhs.Equals(rhs);
}

public static bool operator !=(User lhs, User rhs)
{
    return !lhs.Equals(rhs);
}
Run Code Online (Sandbox Code Playgroud)

  • @rajibdotnet - int 结构是原始类型,因此相等性由编译器实现(通常委托给 cpu 整数比较指令),并且不依赖于类库提供 `operator==` 实现。即便如此,每个结构体都可以自由地实现“operator==”,在这种情况下,OP 的问题就消失了。问题在于结构没有“默认”实现,而类有。 (2认同)