惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog
D
DataBreaches.Net
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
Latest news
Latest news
博客园_首页
T
Tenable Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
Spread Privacy
Spread Privacy
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
I
InfoQ
The Cloudflare Blog
J
Java Code Geeks
C
Cybersecurity and Infrastructure Security Agency CISA
量子位
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
AWS News Blog
AWS News Blog
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
G
Google Developers Blog
Simon Willison's Weblog
Simon Willison's Weblog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
A
Arctic Wolf
D
Darknet – Hacking Tools, Hacker News & Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
Project Zero
Project Zero
P
Privacy International News Feed
Engineering at Meta
Engineering at Meta
G
GRAHAM CLULEY
博客园 - Franky
C
CERT Recently Published Vulnerability Notes

博客园 - 张逸

响应式编程的实践 高质量代码的特征 剖析大数据平台的数据处理 剖析大数据平台的数据存储 剖析大数据平台的数据采集 剖析大数据平台的数据源 DDD峰会归来话DDD 贝叶斯定理与直觉 - 张逸 - 博客园 重新审视演进式设计 - 张逸 - 博客园 设计恰如其分的架构 函数式非凡的抽象能力 或许是领域建模的真相 博客新家(agiledon.github.com) 软件系统的稳定性 真实案例引起的对系统健壮性的思考 调整Virtual Box硬盘大小 LA工作第二周体会 LA工作第一周体会 设计匠艺模型
IsDefined的问题
张逸 · 2011-10-11 · via 博客园 - 张逸

在.NET 4.0(当然也包括4.0以前的版本)下,用反射判断某个方法是否运用了自定义Attribute时,可以通过调用MethodInfo的IsDefined()方法进行确认。当然,IsDefined()方法事实上定义在MethodInfo的父类MemberInfo中,但它仅仅被定义为抽象方法,真正的实现是在MethodInfo的子类DynamicMethod中。调用方式如下所示:

methodInfo.IsDefined(typeof(MyAttribute), false)

然而,在实际开发中,我发现该方法有一个问题。如果获得MethodInfo的方式是通过加载程序集,然后利用反射方式获得的MethodInfo对象,即使该方法运用了自定义Attribute,返回的结果仍然是false。例如,我们将需要判断的方法所在的类定义到一个单独的Project中,并编译为单独的dll文件,然后,利用Assembly的LoadFile()方式获得程序集:

  var assembly = Assembly.LoadFile(assemblyPath);
  var types = assembly.GetExportedTypes();
  types.ToList().ForEach(
      type =>
      {
          var flag =
              type.GetMethods().Where(methodInfo => !methodInfo.IsAbstract).Any(
                  methodInfo => methodInfo.IsDefined(typeof(MyAttribute), false));
          Console.WriteLine("Flag of IsDefined is: {0}", flag);
      }
  );

打印出来的值为false。

反之,如果不是通过加载程序集,而是直接通过typeof()获得的Type,并调用其下MethodInfo.IsDefined()方法,只要该方法被运用了指定的Attribute,返回的结果则为true。

分析原因,大约是获得Type的方式不同所造成的。Assembly类的GetExportedType()实现如下所示:

[SecuritySafeCritical]
public override Type[] GetExportedTypes()
{
    Type[] o = null;
    GetExportedTypes(this.GetNativeHandle(), JitHelpers.GetObjectHandleOnStack<Type[]>(ref o));
    return o;
}

注意,这里返回的Type[]事实上是通过引用方式传递给了JitHelpers的GetObjectHandleOnStack<Type[]>方法中:

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecurityCritical]
internal static ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T: class
{
    TypedReference reference = __makeref(o);
    return new ObjectHandleOnStack(reference.GetPointerOnStack());
}

这里将Type转换成了TypedReference。关键大约就是这里,可惜我无法找到typeof()的具体实现方式。代码追踪到这里,就无法判断这里发生的真实原因了。若要了解.NET底层机制的同学,可以告诉我。

若要解决反射方式无法通过IsDefined()判断的问题,可以调用MethodInfo的GetCustomAttribute()方法。例如:

private static bool IsAppliedWith(this MethodInfo methodInfo, Type attributeType, string attributeName) 
{
    return methodInfo.GetCustomAttributes(attributeType, false).ToString().Contains(attributeName);
}

无论是利用反射加载,还是使用typeof,采用这种方式判断方法是否运用了指定的Attribute,都是能够生效的。