-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C# 9.0 determine if a type is a 'record' via reflection #3732
Comments
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. |
Thanks! The deeper motivation here is to know if a type is both immutable and with value semantics. This is very desirable for me (Inspired by clojure) I try to get all my types like that but is hard in C#. I have a small list of basic and core types that satisfy that and when needed use reflection to check for that etc (mostly in debug mode). Since records satisfy that (and are in fact the main example) I can include them also hence my question. (I can then use reflection to check that all members of the record are themselves immutable with value semantics etc). |
That sounds more like a compile-time analyzer scenario, to flag a type if it's not immutable, rather than a record scenario. It's perfectly possible to create a mutable record, so just being a record is no guarantee of that type of behavior. |
"t's perfectly possible to create a mutable record" -- sounds like that should be documented, i'm sure kofifus and I are not the only people who (without thinking too deeply) would assume that records are readonly ... |
@AartBluestoke I think what is meant is that while all the members of a record are readonly they may be of mutable types which makes the record itself mutable. IMO C# has a real weak point with immutability but I think @333fred comment is true that an analyzer is the better way to go here |
No, you can have setters on record properties. Records do not mean immutable. They have defaults that pull you in that direction, but they are not immutable-only types. |
@333fred ah ok got it .. must say that is disappointing news |
Can an analyzer identify a record ? if yes how ? Thanks |
Yes. An analyzer would be able to tell. It could just examine the syntax if the type. |
Thanks @CyrusNajmabadi , what do you mean by "examine the syntax if the type" ? |
|
thanks @ufcpp |
I wanted to know if a type is a record to avoid serializing the |
Here is a use case: You're registering services for the DI container using assembly scanning, e.g. with Scrutor. You only want services in the container, not any data carriers like DTOs and value objects. Your services probably aren't going to be records, but many data carriers will be. It's a great filter criterion to include. |
But why would you need to enforce that? If someone wants to shove a POD object into a container, why prevent them? |
Use a convention where the type name or namespace needs to end in Attempting to filter "on records" would not be comprehensive enough either way to avoid the situations you are listing, since not all "non-service" classes will be records in the first place, and you'll still end up in a situation where you need to do something else to filter those out anyways. |
Oh, I wasn't implying that detecting records is a full solution to separating services from non-services. But I'm not the only one taking a heuristics-based approach, and detecting records has certainly helped with mine. I'd prefer to do it without my own extension method. I understand that you might choose a different approach to tackle that use case. That's a trade-off concerning purely the use case. Priorities differ. The point was to illustrate that there are reasons for developers to want to know at runtime whether a type is a record. |
If you're ok with a heuristic approach, it's simple. Check for the clone method with the particular name at runtime. |
Yes, or the equality thing. The request is to support this with something like an IsRecord property, rather than rolling your own extension that inspects a type’s methods. (For full clarity, heuristics referred to separating services from non-services, not evaluating whether something is a record.) |
This exists if you use hte Roslyn API. If you want reflection to support this, it has to be a dotnet/runtime request. Roslyn doesn't control that. |
Is there an official way to detrmine if a type is a 'record' via reflection ?
Looking here I was thinking about maybe detecting the
EqualityContract
property:but that feels hackish :(
The text was updated successfully, but these errors were encountered: