Closed mwpowellhtx closed 6 years ago
@mwpowellhtx Sorry, I answered in the chat but didn't see this issue.
When typeof(T)
executes, it will always be replaced with the parameterized type of the class's generic instantiation. typeof(T)
won't be the generic type parameter; it'll be identical to if you had written typeof(int)
or typeof(Foo)
there. If you want the definition itself of the generic type parameter, you need to use GetGenericArguments()
, like this:
typeof(MyClass<>).GetGenericArguments()[0].CustomAttributes
@jnm2 Yes, I know about typeof
, that's not the point. Given a generic type, how do I access the GenericParameterInfo
(?), in order to get the custom attributes of that? The issue is, as I mentioned here, GetGenericArguments
returns a Type[]
, not GenericParameterInfo[]
. If you try GetCustomAttributes
after that, you are getting custom attributes on the Type T
, not on its decoration in the Generic list. Does this make sense? Cook up a simple unit test to demonstrate it for yourself if you don't believe me.
@jnm2 A similar case was observed in the Mono project for Method generics, as compared/contrasted with Class generics.
@mwpowellhtx I had run the code and typeof(MyClass<>).GetGenericArguments()[0].CustomAttributes
returned the MyCustomAttribute
. I'll try again and try to see what I'm missing.
The Type
class represents all the generic parameter info there is, for types that are generic parameters.
@mwpowellhtx
This code:
interface Type
{
void Method<[Obsolete] T>();
}
Doesn't compile with the Roslyn C# compiler:
CS0592: Attribute 'Obsolete' is not valid on this declaration type. It is only valid on 'class, struct, enum, constructor, method, property, indexer, field, event, interface, delegate' declarations.
/cc @jaredpar
While valid in the underlying the IL, I don't think anyone on our end has ever relied on discovering attributes on generic type instantiations. BTW, in IL you can attribute virtually anything, including derived types, which C# also doesn't let you do. The only thing you can't attribute in IL is attribute application. /cc @tmat
In general, I don't believe this issue belongs here as your asking for implementation/API surface changes of a net-new feature. This issue belongs to dotnet/corefx.
@terrajobst Why is this closed? I'm not talking about Method generics, although there may be some similarities there, I do not know; but rather, Class generics?
Who's not relying on it? I am reported it. At least some others have reported this. So obviously, SOME of us are relying on this, or would like to if it were possible.
@terrajobst To be clear, I'm not talking about ObsoleteAttribute
in particular, but rather a custom attribute in my case.
@terrajobst Also, I am targeting .NET Standard
, not .NET Core
, just to be clear about that, so kindly reopen for investigation. Thanks!
@mwpowellhtx Can you come over to https://gitter.im/dotnet/csharplang to follow up on your question and my reply there? I think there's a misunderstanding.
@jnm2 Here is what I get when I pursue the suggested avenue:
| Name | Value | Type
-- | -- | -- | --
▶ | typeof(AssemblyInfoBumpVersionService<T>).GetGenericArguments()[0] | {Name = "AssemblyFileVersionAttribute" FullName = "System.Reflection.AssemblyFileVersionAttribute"} | System.Type {System.RuntimeType}
◢ | a | {System.Attribute[3]} | System.Attribute[]
| ▶ [0] | {System.AttributeUsageAttribute} | System.Attribute {System.AttributeUsageAttribute}
| ▶ [1] | {System.Runtime.InteropServices.ComVisibleAttribute} | System.Attribute {System.Runtime.InteropServices.ComVisibleAttribute}
| ▶ [2] | {__DynamicallyInvokableAttribute} | System.Attribute {__DynamicallyInvokableAttribute}
I find the generic parameter to be AssemblyFileVersionAttribute
correctly so. However, I find custom attributes for the AssemblyFileVersionAttribute
type, not for its parameter decoration.
@terrajobst Turns out the confusion was mine over a difference between typeof(MyClass<T>)
and typeof(MyClass<>)
. Subtle difference and reveals different generic type reflection.
@mwpowellhtx
I closed this issue because I don't think it belongs into this repo but maybe we're talking past each other. Let me rephrase:
This repo only tracks API suggestions for .NET Standard. One requirement is that these API already exist in at least one .NET implementations. As such, I closed this issue.
@terrajobst To clarify, no, my Mono reference is only in terms of reflecting generic type attribution. That's the only parallel there.
Rather, I'm interested to reflect attributes decorating T
in class MyClass<T> {}
.
But this has been resolved.
Ah, I stand corrected. I should have used your repro code instead of the one linked from Mono issue:
[AttributeUsage(AttributeTargets.GenericParameter, AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
public MyCustomAttribute() { }
}
public class MyCustomClass<[MyCustom] T>
{
}
This indeed compiles just fine. And yes, typeof(MyClass<>)
is the one you want to use as that's the original definition:
Type x = typeof(MyCustomClass<>);
Type argument = x.GetGenericArguments()[0];
Type attribute = argument.CustomAttributes.First().AttributeType;
Console.WriteLine(attribute);
Seems similar to this Mono issue, except for Class Generics, not Method Generics.
So any custom attribute, something like:
Literally, I've got a class like this:
I am finding lots of ways to get at the list of Generic Types, per se, but not the list of Generic Parameters, if that makes any sense. In other words, any requests for Custom Attributes appear to be on the
typeof(T)
, but not a sort of theGenericParameterInfo
if there were such a thing.I am targeting .NET Standard 2.0 for a bit of Development Only dependency assembly work.