I am trying to use C# 11 ref struct/fields to create a "ref tuple", that is a type that holds multiple refs.
ref struct RefTuple<T1, T2> {
public ref T1 Item1;
public ref T2 Item2;
public RefTuple(ref T1 item1, ref T2 item2)
{
Item1 = ref item1;
Item2 = ref item2;
}
public bool Equals(RefTuple<T1, T2> o) {
return Equals(Item1, o.Item1) && Equals(Item2, o.Item2);
}
public override bool Equals(object o) {
return o is RefTuple<T1, T2> rt && Equals(rt);
}
public override int GetHashCode() {
retrun HashCode.Combine(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0);
}
public static bool operator ==(RefTuple<T1, T2> obj1, RefTuple<T1, T2> obj2) {
return obj1.Equals(obj2);
}
public static bool operator !=(RefTuple<T1, T2> obj1, RefTuple<T1, T2> obj2) {
return !obj1.Equals(obj2);
}
}
The idea is I can then initialize and pass an object of type RefTuple<T1, T2> to a function using a ref, and that function can then change Item1 etc which will modify the original ref used when initializing the RefValue.
Problems:
Equals(object o)above does not compile seems theisoperator does not work with ref structs ? I am not sure how to correctly implement it.Equals(object o)also shows "Nullability of type of parameter 'o' doesn't match overridden member" which I am not able to resolve. (code has nullability enabled)Equals(RefTuple<T1, T2> o)is usingobject.Equalsbut I believe that may not be efficient as it may end up boxing. I tried insteadItem1.Equals(o.Item1) && Item2.Equals(o.Item2)but then get the nullability warnings above.
There's some limits when using a
ref struct, one of them is:The parameter
oinEquals(object o)can never be the type ofRefTuple, so you can simply return false.The signature of this method in the base class is:
The overridden method need match it.
Even if you call
Item1.Equals(o.Item1), you are still calling the methodEquals(object), boxing cannot be ignored. The built-inValueTupleclass usesEqualityComparer<T1>.Default, maybe this is for reference.