I'm seeing some odd behaviour after using FirstOrDefault() on a collection of structs. I've isolated it into this reproduction case. This program won't compile
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;
}
}
The compiler error is the rather cryptic:
Operator '==' cannot be applied to operands of type 'MyProgram.User' and 'MyProgram.User'
Changing the struct to a class works fine – but I'm at a loss as to why I can't compare a struct 'instance' to a default?
Best Answer
For classes, the
==
operator uses reference equality. Of course, structs are value types, so they can't be compared by reference. There is no default implementation of==
for structs because memberwise comparison isn't always a valid comparison, depending on the type.You can instead use the
Object.Equals
method, which does compare memberwise:Or you could just implement
==
to callObject.Equals
:However, the default implementation of
Equals
for structs uses reflection, and so is very slow. It would be better to implementEquals
yourself, along with==
and!=
(and possiblyGetHashCode
too):