Dynamic in C# 4.0, Part 8

Gieno  Dynamic in C# 4.0, Part 8

After  7 posts on dynamic for learning, this time I think it's much more to fun to use it for something evil… by making Reflection simple.
In C# 3.0 invoking members through reflection, was kind of odd and certainly not very readable.
var employee  =   new  Employee();
var members 
=  employee.GetType().GetMember(  " age " , MemberTypes.All,              
                                                                  BindingFlags.IgnoreCase 
|  BindingFlags.Instance  |
                                                                  BindingFlags.NonPublic 
|  BindingFlags.Public );
((FieldInfo)members[
0 ]).SetValue(employee,  30 );
By wrapping all reflection magic in a dynamic object the same call would look like:
var employee  =  ( new  Employee()).AsDynamic();
employee.Name 
=   " Gieno Miao " ;
employee.Age 
=   26 ;
Console.WriteLine(
" Employee {0} is {1} years old. " , employee.Name, employee.Age);
How this works is relatively easy.. by deriving a wrapper class from the new  DynamicObject and overriding the  TrySetMember and  TryGetMember object to do the dirty work for you.
ContractedBlock.gif ExpandedBlockStart.gif Demo Code
static class DynamicHelper
{
    
public static dynamic AsDynamic(this T source)
    {
        
return new DynamicReflection(source);
    }

    
class DynamicReflection : DynamicObject
    {
        
public DynamicReflection(T source)
            : 
base()
        {
            
this.Source = source;
        }

        
public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            
// find the member
            MemberInfo member;
            
if (!TryFindMember(binder.Name, out member))
            {
                
return false;
            }

            
// we can only set values to fields and properties
            
// using reflection
            switch (member.MemberType)
            {
                
/* todo: check the type of the incoming value and the type of 
                  the property. 
*/
                
case (MemberTypes.Field):
                    ((FieldInfo)member).SetValue(Source, value);
                    
return true;
                
case (MemberTypes.Property):
                    ((PropertyInfo)member).SetValue(Source, value,
/*ndex*/ null); 
                
// we don't support indexed properties
                    return true;
            }

            
// didn't work
            return false;
        }

        
public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            
// find the member
            MemberInfo member;
            
if (!TryFindMember(binder.Name, out member))
            {
                result 
= null;
                
return false;
            }

            
// we can only set values to fields and properties
            
// using reflection
            switch (member.MemberType)
            {
                
/* todo: check the type of the incoming value and the type of 
                  the property. 
*/
                
case (MemberTypes.Field):
                    result 
= ((FieldInfo)member).GetValue(Source);
                    
return true;
                
case (MemberTypes.Property):
                    result 
= ((PropertyInfo)member).GetValue(Source,/*ndex*/ null); 
            
// we don't support indexed properties
                    return true;
            }

            
// didn't work
            result = null;
            
return false;
        }

        
private bool TryFindMember(string name, out MemberInfo memberInfo)
        {
            
// find the member
            var members = Type.GetMember(name, MemberTypes.All,
                                         BindingFlags.IgnoreCase 
| BindingFlags.Instance | 
                         BindingFlags.NonPublic 
| BindingFlags.Public);

            
// more than 1 not supported for now
            if (members.Length != 1) { memberInfo = nullreturn false; }

            memberInfo 
= members[0];
            
return true;
        }

        
private Type Type { get { return typeof(T); } }

        
public T Source { getprivate set; }
    }
}
As always, happy coding.

转载于:https://www.cnblogs.com/gieno/archive/2009/09/16/1567747.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值