Skip to content
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

Add IsGenericTypeParameter and IsGenericMethodParameter to System.Type #23493

Closed
ghost opened this issue Sep 8, 2017 · 8 comments
Closed

Add IsGenericTypeParameter and IsGenericMethodParameter to System.Type #23493

ghost opened this issue Sep 8, 2017 · 8 comments
Labels
api-approved API was approved in API review, it can be implemented area-System.Reflection help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@ghost
Copy link

ghost commented Sep 8, 2017

Proposed apis

class Type
{
    public virtual bool IsGenericTypeParameter => IsGenericParameter && DeclaringMethod == null;
    public virtual bool IsGenericMethodParameter => IsGenericParameter && DeclaringMethod != null;
}

class TypeDelegator (and TypeBuilder,GenericTypeParameterBuilder,EnumBuilder)
{
    public override bool IsGenericTypeParameter { get; }
    public override bool IsGenericMethodParameter { get; }
}

These properties distinguish between generic parameters introduced by types and generic parameters introduced by methods.

Rationale

Currently, the only way to distinguish generic parameters on types from generic parameters on methods is by testing whether DeclaringMethod returns null.

This idiom will not work with the recently added Signature Types (https://github.com/dotnet/corefx/issues/16567) as these types do not have a MethodInfo to return and will always throw on a DeclaringMethod call. While one could work around this today by writing this:

IsGenericMethodParameter => IsGenericParameter && (IsSignatureType || DeclaringMethod != null)

this is not very intuitive, nor is it future-proof as it's not inconceivable that in the future, we may add the ability to create signature types representing unbounded generic type parameters.

Even for regular types, these new properties are more succinct, expressive and allow properly factored underlying implementations (CoreRT) to override with the maximally performant "return true/false" implementations, eliminating a virtual call. Signature Types, of course, will have to override.

Naming

Naming is consistent with the recently added

Type MakeGenericMethodParameter(int position)

api.

@ghost ghost self-assigned this Sep 8, 2017
@terrajobst
Copy link
Member

terrajobst commented Oct 3, 2017

Video

Looks good, but we don't understand why the properties have to be virtual. It seems they are in nature static. At the end you explain that but how would we eliminate the virtual method call?

@ghost
Copy link

ghost commented Oct 3, 2017

"eliminating a virtual call" referred to the fact that the CoreRT implemention would result in one virtual call rather than two (IsGenericParameter + DeclaringMethod).

For this particular case, the apis have to be overridable (or hard-coded to cast-check for SignatureType) because one the key reasons they're being proposed is that it's not safe to call DeclaringMethod on Signature Types.

@karelz
Copy link
Member

karelz commented Oct 3, 2017

Sounds reasonable to me. This is a good candidate for up-for-grabs IMO, do you want to mark it so @atsushikan?

@ghost
Copy link

ghost commented Oct 3, 2017

I've already got the changes locally and it touches files that are only built in closed-source projects.

@ghost
Copy link

ghost commented Oct 3, 2017

It looks like there might be a up-for-grabs on the CoreCLR side but it'll have to wait until I merge my CoreRT stuff and it gets propagated over to CoreCLR through the shared partition. The shared code is actually enough to make the CoreCLR side functional (we can go ahead and expose the api in CoreFx etc.) but the perf there won't be any better than the idiomatic approach today and there's opportunity to improve it there (i.e. don't allocate a MethodInfo just to determine that there is one...)

@karelz
Copy link
Member

karelz commented Oct 4, 2017

FYI: The API review discussion was recorded - see https://youtu.be/m4BUM3nJZRw?t=5730 (3 min duration)

@ghost
Copy link

ghost commented Oct 6, 2017

The apis are now exposed in the contracts and functioning on CoreCLR and CoreRT.

There is an optional "up-for-grabs" perf opportunity in CoreCLR. CoreCLR right now defaults to the fallback implementation on Type.cs, which works but invokes three virtual calls and the unnecessary retrieval of a MethodInfo. It'd be nice to override these two apis here:

https://github.com/dotnet/coreclr/blob/076a61ef2eb3baf69182139f36b948f104e3b740/src/mscorlib/src/System/RtType.cs#L3750

with a custom version that makes just one FCall. The first portion of this FCall:

https://github.com/dotnet/coreclr/blob/076a61ef2eb3baf69182139f36b948f104e3b740/src/vm/runtimehandles.cpp#L1236

contains the logic needed to determine that (1) the type is a generic parameter and (2) which kind it is.

@ghost
Copy link

ghost commented Sep 11, 2018

Closing deadwood issues as part of ownership transfer.

@ghost ghost closed this as completed Sep 11, 2018
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 20, 2020
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Reflection help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

No branches or pull requests

4 participants