关于c#:缺少自定义属性

Missing Custom Attriubutes

在c_中,可以使用反射通过m.CustomAttributes获得成员m的属性(请参阅此属性的文档)。但是,这种方法似乎遗漏了ObjectGetType方法的三个自定义属性(参见.NET Framework 4.6.1参考源中的对象):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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?

也许它与它是一个外部方法这一事实有关?< /打击>

事实上,外在与此无关。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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();
    }
  }
}

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

1
2
3
4
5
6
7
8
9
class MyAttr : Attribute { }
class Program
{
    [Pure]
    [ResourceExposure(ResourceScope.AppDomain)]
    [MethodImpl]
    [MyAttr]
    public void Foo() { }
}

.CustomAttributes只返回MyAttr。我认为这仅仅是因为fcl不会威胁这三个属性作为自定义属性。在源代码中,MethodInfo.CustomAttributes最终调用MetadataImport.EnumCustomAttributes,在这里调用外部方法。

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

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

编辑PureAttributeResourceExposureAttribute是有条件构建的,这就是为什么你不能得到它们。

1
2
3
4
5
[Conditional("RESOURCE_ANNOTATION_WORK")]
public sealed class ResourceExposureAttribute : Attribute

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

江户十一〔六〕似乎很特别。