Cannot enfore generic method to accept record #3859
-
DescriptionWhen creating a generic method on .NET 5, it is not possible to enforce the generic to be a "record" type. Instead "where T: class" needs to be used. In my opinion, this should be possible. It will also hint to the compiler the input is read-only. Example// Compiles. And, oddly enough, allows /records/ to be passed in: For the bot: Label area-TypeSystem-coreclr possibly? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 3 replies
-
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Beta Was this translation helpful? Give feedback.
-
See the recent discussion following #39 (comment), where the conclusion was that this would not be useful, for example:
Keep in mind that records don't have to be read-only. For example, the following is a perfectly valid record: record R
{
public int I { get; set; }
} |
Beta Was this translation helpful? Give feedback.
-
Records are not read only :-) |
Beta Was this translation helpful? Give feedback.
-
As stated in the conversation svick linked, this is very much by design. We'll let this issue stay open as a separate place to discuss this further, but please do read the conversation at that link as it contains a lot of info as to the motivations of the design team here. |
Beta Was this translation helpful? Give feedback.
-
But there is a very important distinction between a class an a record. For a record I can use a interface IBook {
string Author { get; }
string? DisplayName { get; }
string? Description { get; }
}
record SimpleBook : IBook {
public required string Author { get; init; }
public required string ISBN { get; init; }
public required string Content { get; init; }
public string? DisplayName { get; init; }
public string? Description { get; init; }
}
T Read<T>(string filePath) where T : IBook, record {
T content = // deserializing the file from json
var translation = ReadTranslationFor(filePath);
return content with {
DisplayName = translation.DisplayName,
Description = translation.Description
};
}
var myBook = Read<SimpleBook>("~/Documents/Books/my-book.json"); Currently this doesn't work because for the compiler, classes and records are not semantically the same. |
Beta Was this translation helpful? Give feedback.
-
The class constraint does not constrain to classes. It is just a reuse of an existing keyword and means constrain to any reference type. Likewise the structure constraint means constrain to value types. |
Beta Was this translation helpful? Give feedback.
As stated in the conversation svick linked, this is very much by design. We'll let this issue stay open as a separate place to discuss this further, but please do read the conversation at that link as it contains a lot of info as to the motivations of the design team here.