how to easily exclude properties from record equality? #4257
Replies: 7 comments 2 replies
-
|
I believe, by design, the answer here is to implement |
Beta Was this translation helpful? Give feedback.
-
|
@theunrepentantgeek ,i'm also trying to do a source generator for my senarios, where simply a equal override seems not enough |
Beta Was this translation helpful? Give feedback.
-
|
I agree that it's one of the logical growth points for this feature. Reimplementing the whole equality is usually a big pain in the neck if all you need is to add a sequence-equal collection member or exclude a volatile member. An attribute that supplies a different equality comparer for a member would work well, but I would settle for a helper like |
Beta Was this translation helpful? Give feedback.
-
|
Like others suggested, the intended way to solve this is by manually implementing the Equals method. If writing the Equals manually is really too cumbersome in your case or sensitive to mistakes, you can also consider wrapping the member in a type that implements equality as always true. public readonly struct IgnoreEquals<T>(T value) {
public T Value { get; init; } = value;
public override bool Equals(object? obj) => true;
public override int GetHashCode() => 0;
public override string? ToString() => Value?.ToString();
}Then in your record types: record Foo {
private IgnoreEquals<int> _ignoreThisMemberInEquals = new(0);
}This way the compiler generated Equals will still work. |
Beta Was this translation helpful? Give feedback.
-
|
This gives me WPF vibes were when you want to change a simple button color you need to rewrite 200 lines of style/template. I'm so disappointed :( |
Beta Was this translation helpful? Give feedback.
-
|
Ok, this is stupid, may not be the fastest, but if anyone is interested in different workaround, this works and it's least boilerplate solution I could think of. public class DynamicStorage<T> {
private Dictionary<long, Props> dic = [];
private ObjectIDGenerator g = new ObjectIDGenerator();
public Props this[T tx] {
get {
var t = g.GetId(tx, out var ft);
if(dic.TryGetValue(t, out var p)) return p;
dic.Add(t, p = new Props()); return p;
}
}
}
public class Props {
private Dictionary<string, object?> dic = [];
public T? get<T>(string name) => dic.TryGetValue(name, out var v)
? (T?)v : default;
public void Set<T>(string name, T? v) => dic[name] = v;
}Then you use it like this: public record class TargetFramework (
TargetFrameworkName? name,
Version? version,
string? platform = null)
{
private static DynamicStorage<TargetFramework> store = new();
/// <summary>Raw string stored in `TargetFramework(s)` or `TargetFrameworkVersion`.
/// PS. The stupid records don't allow to exclude properties form equality check so currently original "v4.8" would be converted to "net48" for the operators to work as expected.</summary>
public string? sourceString {
get => store[this].get<string>(nameof(sourceString));
private set => store[this].Set(nameof(sourceString), value);
}
//...This will allows me to have two different var t1 = (TargetFramework)"net48";
var t2 = (TargetFramework)"v4.8";
Console.WriteLine(t1.sourceString); //net48
Console.WriteLine(t2.sourceString); //v4.8
Console.WriteLine(t1 == t2); //true |
Beta Was this translation helpful? Give feedback.
-
|
Hello everyone. Although I don't know if it's useful for you. But perhaps you can take a look. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
i have a record
where User is not a init property and i dont want it to be within equality consideration.
any easy way to make it happen?
Beta Was this translation helpful? Give feedback.
All reactions