C# 9 records: how to specify a generic type T that must be a record

127 views Asked by At

I am experimenting with the C# 9 RC, converting an existing application to use the new record construct and associated with keyword.

A high proportion of my defined record types implement this interface (modified to use the init keyword instead of set):

public interface IHasModifiedDate
{
    DateTime ModifiedDate {get; init;}
}

(Note: the specific classes that implement this interface don't - and can't - have a common superclass).

I am trying to update a generic helper function that allows the modified date to be updated (where 'updated' now means: create a new instance with just that field change, using with) i.e.:

public static T UpdateModifiedDate<T>(T obj, DateTime whenTo) where T: IHasModifiedDate 
{
    return obj with {ModifiedDate = whenTo};
}

This gives the (reasonable) compile error: The receiver type 'T' is not a valid record type, and hence the with keyword cannot be used.

I would like to be able to add the constraint on T specifying that T is in fact a record (in the same way that you can specify that T must be a class) e.g:

public static T UpdateModifiedDate<T>(T obj, DateTime whenTo) where T: record, IHasModifiedDate 
{
    return obj with {ModifiedDate = when};
}

but the record keyword is not recognised in this context.

Is there any other way to specify that T is a record?

0

There are 0 answers