Let's assume I have several different record
-types with a common interface, as follows:
record Rec1(
string Tag
) : IFoo;
record Rec2(
int Num,
string Tag
) : IFoo;
record Rec3(
bool Flag
) : IFoo
{
public string Tag { get; init; }
public double Value { get; init; }
}
// ... others ...
interface IFoo
{
string Tag { get; }
}
My goal is to write a function to update the Tag property via record clonation.
Now, if the type were known, I could write something like this:
private Rec2 Update(Rec2 rec, string tag)
{
return rec with { Tag = tag };
}
However, I would avoid to write a bunch of overloads, so I'm wondering if there's a more generic way to achieve that. For instance, I'd tempted to write as:
private TRec Update<TRec>(TRec rec, string tag) where TRec : IFoo
{
return rec with { Tag = tag };
}
but that won't compile, because TRec
could be anything (class
, struct
, etc), not just a record
where I can use the with
statement. By the way, there's no a record
-constraint I could apply.
So, is there any workaround? is it anything to expect to be solved in the future?
As a bonus question (just for sake of curiosity), why a record
-translated class isn't marked with a special interface, in order to make the with
statement working against?
CodePudding user response:
Instead of having an empty base record, have all these records inherit from a shared base record, that implements your interface:
record R : IFoo ...
record Rec1 : R....
record Rec2 : R....
private TRec Update<TRec>(TRec rec, string tag) where TRec : R
{
return rec with { Tag = tag };
}
CodePudding user response:
Thanks to another answer (see link in the comments), it seems to be a hacky workaround:
record R();
record Rec1(
string Tag
) : R, IFoo;
// ... others ...
interface IFoo
{
string Tag { get; init; }
}
private TRec Update<TRec>(TRec rec, string tag) where TRec : R, IFoo
{
return rec with { Tag = tag };
}
The constraint is effective due the R
record, while the Tag
assignment thanks to the init
accessor.
Again, to me is much like a hack than a real solution. I'd prefer to see some native support.