-
Notifications
You must be signed in to change notification settings - Fork 4.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
(idea) Adding a 'static if' construct to support generic specialization #8871
Comments
I don't know. I can see how it would be useful, but something seems wrong. |
Maybe this need CLR support? |
Probably not, as the compiler can just create an extra variable for each Jonathan Allen On Thu, Feb 18, 2016 at 1:32 AM, Paul Chen notifications@github.com wrote:
|
What if a method using this feature is called from another generic method that doesn't use this feature? |
This seems like it'd be better as an extension to the void Foo<T>( T x ) where T : sbyte, short, int, long
{
// x is guaranteed to be a signed integer value
} I'm all for lifting features from D and dropping them into C# wholesale - and there are plenty of features I'd like to borrow - but the addition of |
A relevant CoreCLR issue: https://github.com/dotnet/coreclr/issues/2591 |
F# has it. But it's implemented on top of statically resolved generics. Also see this relevant blog post. |
What IL would that compile to?
I believe you can use |
I like that a lot more. Besides just feeling better, it opens the door to useful things like support for arithmetic and comparison operations. -----Original Message----- This seems like it'd be better as an extension to the where clause. |
How would that be a problem? As long as the method's initial constraints on T are a superset of the calling method's, I don't see how that could cause errors. e.g: void A<T>() where T : class
{
B<T>();
}
void B<T>()
{
static if (T == Foo)
...
else ...
} |
@SirTony How would that help in specialization, though? As far as I can see, your method can only be called with a concrete type (e.g. |
A generic |
Actually private int GetCodeForType<T>()
{
if (typeof(T) == typeof(byte)) return 1;
if (typeof(T) == typeof(DateTime)) return 2;
return 3;
} Will be JIT compiled to |
Example of usage of partial specialization:
The above code could for example be used to deserialize XML data content into deduplicated in memory data structures. To be closer to the current type constraints I would recommend a different syntax:
This will in fact generate |
We are now taking language feature discussion in other repositories:
Features that are under active design or development, or which are "championed" by someone on the language design team, have already been moved either as issues or as checked-in design documents. For example, the proposal in this repo "Proposal: Partial interface implementation a.k.a. Traits" (issue 16139 and a few other issues that request the same thing) are now tracked by the language team at issue 52 in https://github.com/dotnet/csharplang/issues, and there is a draft spec at https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md and further discussion at issue 288 in https://github.com/dotnet/csharplang/issues. Prototyping of the compiler portion of language features is still tracked here; see, for example, https://github.com/dotnet/roslyn/tree/features/DefaultInterfaceImplementation and issue 17952. In order to facilitate that transition, we have started closing language design discussions from the roslyn repo with a note briefly explaining why. When we are aware of an existing discussion for the feature already in the new repo, we are adding a link to that. But we're not adding new issues to the new repos for existing discussions in this repo that the language design team does not currently envision taking on. Our intent is to eventually close the language design issues in the Roslyn repo and encourage discussion in one of the new repos instead. Our intent is not to shut down discussion on language design - you can still continue discussion on the closed issues if you want - but rather we would like to encourage people to move discussion to where we are more likely to be paying attention (the new repo), or to abandon discussions that are no longer of interest to you. If you happen to notice that one of the closed issues has a relevant issue in the new repo, and we have not added a link to the new issue, we would appreciate you providing a link from the old to the new discussion. That way people who are still interested in the discussion can start paying attention to the new issue. Also, we'd welcome any ideas you might have on how we could better manage the transition. Comments and discussion about closing and/or moving issues should be directed to #18002. Comments and discussion about this issue can take place here or on an issue in the relevant repo. Type classes would support this feature request, but with a completely different and typesafe syntax, and are under consideration at dotnet/csharplang#110 |
I was thinking about this a month ago or so when I read through the code of
EqualityComparer
. It had lots of code like this:Obviously, while this is not a very common case, it's far from ideal. If we accidentally swapped
byte
andshort
for example, the library would still compile and we'd only get an exception at runtime.Idea: static if
My idea is to have a
static if
construct (similarly to DLang), that the compiler could use to infer the type of T when specialized. With it, the code above would look like this:Of course, this wouldn't be the only use case for this statement. It could also improve performance in classes like
List<T>
, to specialize outBuffer.BlockCopy
for the primitive types:Another case where this can be used is to supplant
typeof(T).IsAssignableFrom
, which is 1) not available in .NET Core, and 2) can't be optimized by the JIT. So code that looks like this:could get transformed to this:
which reads much more naturally. (The compiler could also do things like emit warnings if T is a struct, which it can't do with the runtime APIs.)
This could also be used to check if a type is a struct or a class, for instance:
Anyway, that's just my two cents. It should be clear that this is not a fully-formed proposal, it's just an idea I've been thinking about for a while in my head.
What do you guys think?
The text was updated successfully, but these errors were encountered: