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

推荐订阅源

U
Unit 42
N
News and Events Feed by Topic
S
Schneier on Security
G
GRAHAM CLULEY
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
T
The Exploit Database - CXSecurity.com
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
Cisco Talos Blog
Cisco Talos Blog
P
Privacy & Cybersecurity Law Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
Blog — PlanetScale
Blog — PlanetScale
Project Zero
Project Zero
MyScale Blog
MyScale Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
The Last Watchdog
The Last Watchdog
Vercel News
Vercel News
The Cloudflare Blog
C
Check Point Blog
Help Net Security
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
腾讯CDC
NISL@THU
NISL@THU
S
Security @ Cisco Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
AWS News Blog
AWS News Blog
Cloudbric
Cloudbric
N
News and Events Feed by Topic
PCI Perspectives
PCI Perspectives
S
Securelist
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Vulnerabilities – Threatpost
S
Secure Thoughts

博客园 - 浪子

你真的懂HTML吗-从"最新闪存"说起 LINQ TO SQLite实践指南 [TDD]由SearchCriteriaBinder看Test Driven与Test First [OpenSource] ScriptLoader V5:不一样的体验,客户端分布式缓存平台 [OpenSource] ScriptLoader V4:与组件系统共舞,让分享更清晰 [OpenSource]ScriptLoaderV2:彻底改变你的编程习惯 [OpenSource]ScriptLoader: 轻松管理你的js 类库 关于Windows Mobile 6 Professional Emulator中的一个串口设置小问题. 文件被数字签名策略拒绝(File was rejected by digital signature policy) [开源第一波]SmartScript Ajax中动态执行返回到innerHTML中的js [Silverlight探秘]深入探索Silverlight与Javascript的交互 [Silverlight探秘]利用Silverlight调用Javascript的方法 [Silverlight探秘]利用Javascript调用silverlight的方法 encodeURI/decodeURI与UrlEncode/UrlDecode,噩梦在继续 [MapEasy]浅析ListenerSupport 技术人,什么才是你的成功? [Flash FileUpload]用flash.net.FileReference实现ASP.NET无刷新文件上传 [SmartScript]js类库管理不再发愁
LINQ TO Reflection(反射)
浪子 · 2010-08-11 · via 博客园 - 浪子

引言

我们平时开发中不可避免,或者说,经常性的使用反射。但是却没有一个合适的类库帮助我们更好的利用反射。从早期的FastInvoker,到老赵的 fastreflectionlib ,无一不是在强调Fast。这是因为反射的性能损耗比较厉害,所以大家都集中精力解决性能的问题,但是在易用性方面却鲜有改进。今天我为大家带来一个即兼顾性能又具有良好的使用体验的反射类库.

.Metadata()

此类库以LINQ TO Object为基础,可以通过调用.Metadata()方法获取对应Type的完整Metadata信息。此信息会被进行缓存,并且使用fastreflectionlib的核心Lambda代码,利用DynamicMethod代替直接的反射执行。

        public static Metadata Metadata(this object instance)
{
return MetadataCache.Create(instance);
}

     先定义一个MockObject

        class MockAttribute : Attribute
{
public MockAttribute(string name)
{
this.Name = name;
}
public string Name
{
get;set;
}
}

class MockObject
{
public string Country = "China";

[Mock("this is the name")]
public string Name
{
get;set;
}
public string Blog
{
get;set;
}
[Mock("this is the location")]
public string Location
{
get;set;
}
public string SayHello(string name)
{
return "Hi," + name;
}
}
}

   1.如何获取一个属性,并进行取值、赋值?

        using Sparrow.Reflection;
[TestMethod]
public void set_property_value()
{
var obj = new MockObject { Name = "dayi", Blog = "http://walkingboy.cnblogs.com", Location = "XiaMen" };
var property = obj.Metadata().Properties.Where(i => i.Name == "Location").FirstOrDefault();
var changedLocation = "Xiamen,China";
//get value //var value = property.GetValue(obj); property.SetValue(obj, changedLocation); Assert.AreEqual(changedLocation, obj.Location); }

   2.如果获取一个字段的值?

        using Sparrow.Reflection;
[TestMethod]
public void get_field_value()
{
var obj = new MockObject();

var field = obj.Metadata().Fields.Where(i => i.Name == "Country").FirstOrDefault();

Assert.AreEqual("China", field.GetValue(obj));
}

   3.如何获取一个自定义CustomAttribute?

        using Sparrow.Reflection;
[TestMethod]
public void get_custom_attribute_data()
{
var obj = new MockObject { Name = "dayi", Blog = "http://walkingboy.cnblogs.com", Location = "XiaMen" };

var attribute = obj.Metadata().Properties
.Where(i => i.Name == "Name")
.SelectMany(i => i.Attributes)
.Select(i=>i.Attribute)
.OfType<MockAttribute>()
.FirstOrDefault();

Assert.AreEqual("this is the name", attribute.Name);
}

   4.如何调用一个指定名称的Method?

        using Sparrow.Reflection;
[TestMethod]
public void invoke_method()
{
var obj = new MockObject();

var method = obj.Metadata().Methods.Where(i => i.Name == "SayHello").FirstOrDefault();

Assert.AreEqual("Hi,world",method.Invoke(obj,new []{"world"}));
}

.Proxy()

对于某些应用场景来说,使用LINQ To Object去查询并获取单一的方法、属性,字段,总觉得还是要写非常多的代码。要先.Metadata(), 接下来.Where(), 虽然代码很优雅,但是还是有很多工作要做。所以这里也提供一个针对获取单一方法、属性、字段的替代写法。

        public static Proxy Proxy(this object instance)
{
return new Proxy(instance);
}

1.如何获取一个属性的值

        using Sparrow.Reflection;
[TestMethod]
public void get_value_via_property_proxy()
{
var obj = new MockObject { Name = "dayi", Blog = "http://walkingboy.cnblogs.com", Location = "Xiamen" };

Assert.AreEqual(obj.Name, obj.Proxy().Properties["Name"]);
}

2.如何设置一个属性的值

        using Sparrow.Reflection;
[TestMethod]
public void set_value_via_property_proxy()
{
var obj = new MockObject { Name = "dayi", Blog = "http://walkingboy.cnblogs.com", Location = "Xiamen" };

var changedLocation = "Xiamen,China";
obj.Proxy().Properties["Location"] = changedLocation;

Assert.AreEqual(changedLocation,obj.Location);
}

3.如何获取一个字段的值

        using Sparrow.Reflection;
[TestMethod]
public void get_value_via_field_proxy()
{
var obj = new MockObject { Name = "dayi", Blog = "http://walkingboy.cnblogs.com", Location = "Xiamen" };

Assert.AreEqual(obj.Country, obj.Proxy().Fields["Country"]);
}

4.如何调用一个方法

        using Sparrow.Reflection;
[TestMethod]
public void invoke_method_via_method_proxy()
{
var obj = new MockObject();

Assert.AreEqual("Hi,world", obj.Proxy().Methods["SayHello"](new []{"world"}));
}

.Proxy() Vs Dynamic

我们知道在C# 4中引入了关键字Dynamic,使得 Duck Typing (DynamicDuck: Duck Typing in a Dynamic World) 成为一种可能。 查看如下代码

        public void Run(dynamic obj)
{
Console.WriteLine(obj.Name);
}

这个代码并没有指定参数obj的类型,obj的类型是由运行时候传入的真实值决定,只要该类型包含一个Name的属性就可以了。

但是仅仅支持Duck Typing就够了嘛? 似乎不够动态哦。这边的.Name 是在编译时(或者说编码时)就确定,但是往往我们的使用场景中,连这个也都是动态,比如是接受自Form,或者来自配置信息,这个时候dynamic就无能为力了。

反过来看看使用.Proxy()的情况

       public void Run(object obj,string propertyName)
{
Console.WriteLine(obj.Proxy().Properties[propertyName])
}

不仅支持Duck Typing,同时也支持属性名称的动态化,是不是很有脚本(javascript…)的感觉呢?

代码下载http://sparrow.codeplex.com/releases/view/50364

详细文档http://sparrow.codeplex.com/wikipage?title=LINQ-To-Reflection

本文基于署名 2.5 中国大陆许可协议发布,正品行货,如有雷同,皆为山寨,作者保留追究权利,在保留本文的署名浪子(包含链接)的情况下,允许进行转载,演绎或用于商业目的。如您有任何疑问或者授权方面的协商,请用E-Mail/MSN联系我。