浏览 3290 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-05-30
在工作中看到 不使用反射进行C#属性的运行时动态访问:http://www.cnblogs.com/nankezhishi/archive/2012/02/11/dynamicaccess.html这篇文章后觉得很不错!但是在运用其代码的过程中也发现了这个代码存在的一些bug,经过努力,已经把它fix掉了,而且还增加了一个抛出异常的辅助类,现在分享我修改后的代码:
修改了在PropertyAccessor构造时抛出找不到GET SET Method的异常。
此异常的原因是因为有些property没有public Get 或者Set方法,导致propertyInfo.GetGetMethod()/GetSetMethod() 时返回null,继而导致Delegate .CreateDelegate创建失败。
using System; using System.Collections.Generic; namespace XXX.Common { public interface INamedMemberAccessor { object GetValue(object instance); void SetValue(object instance, object newValue); } public interface IMemberAccessor { object GetValue(object instance, string memberName); void SetValue(object instance, string memberName, object newValue); } internal class PropertyAccessor<T, P> : INamedMemberAccessor { private Func<T, P> GetValueDelegate; private Action<T, P> SetValueDelegate; public PropertyAccessor(Type type, string propertyName) { var propertyInfo = type.GetProperty(propertyName); if (null != propertyInfo) { var getMethodInfo = propertyInfo.GetGetMethod(); if (null != getMethodInfo) { GetValueDelegate = (Func<T, P>)Delegate.CreateDelegate(typeof(Func<T, P>), getMethodInfo); } var setMethodInfo = propertyInfo.GetSetMethod(); if (null != setMethodInfo) { SetValueDelegate = (Action<T, P>)Delegate.CreateDelegate(typeof(Action<T, P>), setMethodInfo); } } } public object GetValue(object instance) { Guard.ArgumentNotNull(GetValueDelegate, "The Property isn't have GetMethod"); return GetValueDelegate((T)instance); } public void SetValue(object instance, object newValue) { Guard.ArgumentNotNull(SetValueDelegate, "The Property isn't have SetMethod"); SetValueDelegate((T)instance, (P)newValue); } } public class MemberAccessor : IMemberAccessor { #region Singleton private MemberAccessor() { } public static MemberAccessor Instance { get { return Nested.instance; } } private class Nested { static Nested() { } internal static readonly MemberAccessor instance = new MemberAccessor(); } #endregion private static Dictionary<string, INamedMemberAccessor> accessorCache = new Dictionary<string, INamedMemberAccessor>(); public object GetValue(object instance, string memberName) { return FindAccessor(instance, memberName).GetValue(instance); } public void SetValue(object instance, string memberName, object newValue) { FindAccessor(instance, memberName).SetValue(instance, newValue); } private INamedMemberAccessor FindAccessor(object instance, string memberName) { Type type = instance.GetType(); string key = type.FullName + memberName; INamedMemberAccessor accessor; if (!accessorCache.TryGetValue(key, out accessor) && accessor == null) { accessor = Activator.CreateInstance(typeof(PropertyAccessor<,>).MakeGenericType(type, type.GetProperty(memberName).PropertyType), type, memberName) as INamedMemberAccessor; Guard.ArgumentNotNull(accessor, "accessor"); accessorCache.Add(key, accessor); } return accessor; } } }
using System; namespace XXX.Common { /// <summary> /// Common guard clauses /// </summary> public static class Guard { /// <summary> /// Checks an argument to ensure it isn't null /// </summary> /// <param name="argumentValue">The argument value to check.</param> /// <param name="argumentName">The name of the argument.</param> public static void ArgumentNotNull(object argumentValue, string argumentName) { if (argumentValue == null) { var ex = new ArgumentNullException(argumentName); } } } }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |