缺少自定义属性

Missing Custom Attriubutes

在 C# 中,可以使用反射通过 m.CustomAttributes 获取成员 m 的属性(参见 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?

可能跟external方法有关?

其实外挂与此无关

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();
    }
  }
}

不是因为方法是外部的。尝试使用用户定义的 class:

class MyAttr : Attribute { }
class Program
{
    [Pure]
    [ResourceExposure(ResourceScope.AppDomain)]
    [MethodImpl]
    [MyAttr]
    public void Foo() { }
}
仅限

.CustomAttributes returns MyAttr。我认为这仅仅是因为 FCL 不威胁这三个属性作为自定义属性。查看源代码,MethodInfo.CustomAttributes最后调用了MetadataImport.EnumCustomAttributes,这里调用了一个外部方法。

[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void _Enum(IntPtr scope, int type, int parent, out MetadataEnumResult result);

我没有调试它,但我认为这种方法知道一些内置属性并将它们从自定义属性中排除是有道理的。

EDIT PureAttributeResourceExposureAttribute 是有条件的,所以你不能得到它们。

[Conditional("RESOURCE_ANNOTATION_WORK")]
public sealed class ResourceExposureAttribute : Attribute

[Conditional("CONTRACTS_FULL")]
public sealed class PureAttribute : Attribute

看来MethodImplAttribute很特别