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
Feature Request: "Refined Value Type" #2369
Comments
In what way? What does a "ValueType" field compile to? How do you use it? What makes it different from either of the other proposals, which are also just syntax sugar? |
This would be an Int32:
It would be comparable to an Int32:
And it would "inherit" all static methods of an Int32 (as it is an Int32):
I see this suggestion as a more simple implementation. :-) |
I don't get it. What's the point if Can you give an example as to what your code would compile to? |
I am not a language designer, so I cannot give you that example, but I can show you how I would use it. :-)
|
Without those details it's kind of difficult to ascertain exactly what you're looking to accomplish with this proposal.
If it's not ok to pass an |
Something like this:
|
So then |
Or, ArtistId is an Int32 and the I'll leave the implementation details to people more intelligent than me :-) |
The C++ community has long had a concept of "strong typedef" that accomplishes this. Type safety is exactly the point of it and it can be super useful to help the author create code free of errors by forcing some form of cast to get at the actual type. I'd give this a weak +1, weak only because a wrapper struct can accomplish the same thing and is more flexible re: error checking that a value is within limits. |
The syntax is much less important than what you want that syntax to accomplish. I'm trying to unpack exactly what this proposal is attempting to accomplish which is difficult to do from a blob of invented syntax. The language team isn't very likely to pick up a proposal that doesn't give them something actionable. I would put that sample code for working with the type in your proposal as that is definitely a big part of it. Indeed, this feels like something between aliases and case classes. I'm all for the concept, but I'm not sure how this specific syntax gets us there. For example, these things are declared as fields/properties, but they're treated as types. That seems to really limit where and how you can use them, not to mention the issues that would arise if you have the same name declared in two separate types. This proposal seems to want the alias to be erased and replaced with the underlying type, which opens a huge can of worms when it comes to metadata representation. But we don't even have a full proposal to discuss. |
@HaloFour wherever we have functions that take an Int or string, visual studio automatically shows the variable name, to help you avoid you putting the "integer-that-is-a-person's-age" into the "integer-that-is-a-userID" slot. Which is easier to use:
The only current mechanism is to trust the user to put the right type of int into the current slot. If we were to do this with classes and propose something that looked like : These types would be implicit-cast Covarient, and explicit cast Contravairent with their underlying type. They could even compile transparently into their underlying valuetype, with just an annotation on functions accepting them as parameters. What they are not is assignable to sibling types of the same value type, giving us compile time type safety over specific uses of integers, string, and boolean. |
I'm aware of the concept. I'm not opposed to a solution here. I personally advocate for case classes or single case union types. As proper types not only do you get better support from the type system and the rest of the ecosystem, but you have the opportunity to add custom validation, equality, comparison operators, etc. The records proposal seems to get us there with as little required boilerplate as: public class UserID(int Value); If they can be value types then all the better as the CLR is good at optimizing them away. |
Yes, thank you for explaining my intentions, when I am not able to make them clear myself :-) |
To me the important thing is to obtain the functionality, the syntax is less important. |
This sound very similar to inline classes of Kotlin |
And C# this would just be using Int32 = Whatver It's called a the using directive.. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive I think we need to refine this proposal 🤗 |
Problem with using directive is that it is per file using Minute = System.Int32; Will allow code like this Minute duration = 5; Or like this /// <summary>
/// Send email to target after delay
/// </summary>
/// <param name="email">Model for email to be sent</param>
/// <param name="delay">Delay before it should be sent</param>
public static void SendEmail(Email email, Minute delay = 0)
{
// TODO
} But my library users will see this public static void SendEmail(Email email, int delay = 0) Kotlin inline classes are visible to method users |
Unless I'm missing something important (always a possibility), a proper semantic type gives you everything you want - and can already be implemented in C# without any language changes. If you check out the discussion of #1300 (Proposal: Add support for typedef (like in C++)), you'll see that this has been heavily discussed before. I did some benchmarking that not only shows no memory allocation but no meaningful peformance difference between a semantic type and a primitive one. |
Closing as due to a github bug I can't move this to a discussion, and this issue doesn't have much support. Feel free to create a new discussion and reference this issue. |
When I write entity classes that I use with Entity Framework, I would like to do something like this:
ArtistId is an Int32 with a little bit more. It is a Refined Value Type that I can use anywhere in my code. I can use it to make sure that I pass the right ID in my services. If I pass an Int32 I would get an error when I try to compile the code.
I image an refined Value Type could be defined something like this:
And it would be great if the Refined Value Type could be decorated with attributes like this:
I know this is a big change. :-)
It would be wonderful to be able to write services with strong verification of the types used.
The text was updated successfully, but these errors were encountered: