Search code examples
c#c#-9.0record-classes

c# 9.0 records - reflection and generic constraints


Two questions regarding the new records feature :

  1. How do I recognize a record using reflection ? looking [here][1] maybe there is a way to detect the EqualityContract but I am not sure if that is the way to go ?

  2. Is it possible to have a generic constraint that a generic type is a record ? that is if it is possible to indicate that type parameter T must be a record class using a constraint ?


Solution

  • How do I recognize a record using reflection ?

    As pointed out here and here

    There is not only not an official way to do this, it is explicitly against the design of the feature. The intent for records is that, hopefully with C# 10, we'll get to a point where making a class a record is purely a convenience choice, and that every other part of the feature will be achievable through some form of syntax. It should not be a breaking change to change a type from a record to a class, and we even imagine that an IDE refactoring could automatically move a type to and from record syntax without clients noticing. For C# 9 there are some places where we didn't quite achieve this, but that's the goal.

    Despite the above there are still scenarios where checking for record us useful. Some hackish ways to detect records which work ATM are:

    1. check if there is an EqualityContract property with the CompilerGenerated attribute
    isRecord = ((TypeInfo)t).DeclaredProperties.Where(x => x.Name == "EqualityContract").FirstOrDefault()?.GetMethod?.GetCustomAttribute(typeof(CompilerGeneratedAttribute)) is object;
    
    1. check for <Clone>$ member as pointed out by @Yair Halberstadt
    isRecord = t.GetMethod("<Clone>$") is object;
    

    or a combination of both

    Is it possible to have a generic constraint that a generic type is a record ?

    No