Reputation: 1725
In C#, one can use reflection to obtain the attributes on a member m
via m.CustomAttributes
(see the documentation for this property). However, this approach seems to miss three custom attributes on the GetType
method of Object
(see the Object in the Reference Source for .NET Framework 4.6.1):
using System;
using System.Linq;
namespace ConsoleApplication1 {
public class Program {
public static void Main(string[] args) {
var desiredCustomAttributes = typeof(object)
.GetMethods()
.First(m => m.Name == "GetType")
.CustomAttributes
.Select(ca => ca.ToString())
.Where(s =>
s.Contains("Pure") ||
s.Contains("ResourceExposure") ||
s.Contains("MethodImplAttribute"));
var n = desiredCustomAttributes.Count();
Console.WriteLine("Expected: 3");
Console.WriteLine(" Actual: " + n); // prints " Actual: 0"
Console.ReadKey();
}
}
}
Why do these three custom attributes not show up?
Maybe it has something to do with the fact that it is an external method?
Actually, being external has nothing to do with it.
using System;
using System.Linq;
using System.Runtime.Versioning;
namespace ConsoleApplication1 {
public class ResourceExposureAttributeOnConstructor {
[ResourceExposure(ResourceScope.None)]
public ResourceExposureAttributeOnConstructor() { }
}
public class Program {
public static void Main(string[] args) {
var n = typeof(object)
.GetConstructors()
.First()
.CustomAttributes
.Select(ca => ca.ToString())
.Where(s => s.Contains("ResourceExposure"))
.Count();
Console.WriteLine("Expected: 1");
Console.WriteLine(" Actual: " + n); // prints " Actual: 0"
Console.ReadKey();
}
}
}
Upvotes: 1
Views: 720
Reputation: 43523
It's not because the method is external. Tried with a user defined class:
class MyAttr : Attribute { }
class Program
{
[Pure]
[ResourceExposure(ResourceScope.AppDomain)]
[MethodImpl]
[MyAttr]
public void Foo() { }
}
.CustomAttributes
returns MyAttr
only. I think it's simply because FCL don't threat the three attributes as custom attributes. Looking into the source code, MethodInfo.CustomAttributes
finally invokes MetadataImport.EnumCustomAttributes
, where an external method is called.
[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void _Enum(IntPtr scope, int type, int parent, out MetadataEnumResult result);
I didn't debug into it, but I think it makes sense that this method knows some built-in attributes and excludes them from custom attributes.
EDIT PureAttribute
and ResourceExposureAttribute
are conditionally built, that's why you can't get them.
[Conditional("RESOURCE_ANNOTATION_WORK")]
public sealed class ResourceExposureAttribute : Attribute
[Conditional("CONTRACTS_FULL")]
public sealed class PureAttribute : Attribute
It seems that MethodImplAttribute
is special.
Upvotes: 1