using System;
using System.Collections.Generic;
using System.Reflection;
namespace XXX.Common
{
internal interface INamedMemberAccessor
{
object GetValue(object instance);
void SetValue(object instance, object newValue);
}
///
/// Abstraction of the function of accessing member of a object at runtime.
///
public interface IMemberAccessor
{
///
/// Get the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The member value
object GetValue(object instance, string memberName);
///
/// Set the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The new value of the property for the object instance.
void SetValue(object instance, string memberName, object newValue);
}
internal class PropertyAccessor : INamedMemberAccessor
{
private Func m_GetValueDelegate;
private Action m_SetValueDelegate;
public PropertyAccessor(PropertyInfo propertyInfo)
{
Guard.ArgumentNotNull(propertyInfo, "Property can't be null");
var getMethodInfo = propertyInfo.GetGetMethod();
if (null != getMethodInfo)
{
m_GetValueDelegate = (Func)Delegate.CreateDelegate(typeof(Func), getMethodInfo);
}
var setMethodInfo = propertyInfo.GetSetMethod();
if (null != setMethodInfo)
{
m_SetValueDelegate = (Action)Delegate.CreateDelegate(typeof(Action), setMethodInfo);
}
}
public object GetValue(object instance)
{
Guard.ArgumentNotNull(m_GetValueDelegate, "The Property doesn't have GetMethod");
return m_GetValueDelegate((T)instance);
}
public void SetValue(object instance, object newValue)
{
Guard.ArgumentNotNull(m_SetValueDelegate, "The Property doesn't have SetMethod");
m_SetValueDelegate((T)instance, (P)newValue);
}
}
///
/// Singleton, MemberAccessor used to accessing member of a object at runtime.
///
public class MemberAccessor : IMemberAccessor
{
#region Singleton
private MemberAccessor() { }
public static MemberAccessor Instance
{
get { return Nested.m_instance; }
}
private class Nested
{
static Nested() { }
internal static readonly MemberAccessor m_instance = new MemberAccessor();
}
#endregion
private static Dictionary m_accessorCache = new Dictionary();
///
/// Get the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The member value
public object GetValue(object instance, string memberName)
{
INamedMemberAccessor ma = FindAccessor(instance, memberName);
Guard.ArgumentNotNull(ma, "The instance doesn't have this property");
. return ma.GetValue(instance);
. }
.
. ///
. /// Set the member value of an object.
. ///
. /// The object to get the member value from.
. /// The member name, could be the name of a property of field. Must be public member.
. /// The new value of the property for the object instance.
. public void SetValue(object instance, string memberName, object newValue)
. {
. INamedMemberAccessor ma = FindAccessor(instance, memberName);
. Guard.ArgumentNotNull(ma, "The instance doesn't have this property");
. ma.SetValue(instance, newValue);
. }
.
. private INamedMemberAccessor FindAccessor(object instance, string memberName)
. {
. Type type = instance.GetType();
. string key = type.FullName + memberName;
.
. INamedMemberAccessor accessor = null;
. if (!m_accessorCache.TryGetValue(key, out accessor))
. {
. #region bug fix from Ambiguous Match Exception
. PropertyInfo propInfo = type.GetProperty(memberName, BindingFlags.DeclaredOnly |
. BindingFlags.Public | BindingFlags.NonPublic |
. BindingFlags.Instance);
. if (null == propInfo)
. {
. propInfo = type.GetProperty(memberName);
. }
. #endregion
. if (null == propInfo)
. {
. return null;
. }
. else
. {
. accessor = Activator.CreateInstance(typeof(PropertyAccessor<,>).MakeGenericType(type, propInfo.PropertyType), propInfo) as INamedMemberAccessor;
. m_accessorCache.Add(key, accessor);
. }
. }
. return accessor;
. }
. }
. }
using System;
using System.Collections.Generic;
using System.Reflection;
namespace XXX.Common
{
internal interface INamedMemberAccessor
{
object GetValue(object instance);
void SetValue(object instance, object newValue);
}
///
/// Abstraction of the function of accessing member of a object at runtime.
///
public interface IMemberAccessor
{
///
/// Get the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The member value
object GetValue(object instance, string memberName);
///
/// Set the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The new value of the property for the object instance.
void SetValue(object instance, string memberName, object newValue);
}
internal class PropertyAccessor : INamedMemberAccessor
{
private Func m_GetValueDelegate;
private Action m_SetValueDelegate;
public PropertyAccessor(PropertyInfo propertyInfo)
{
Guard.ArgumentNotNull(propertyInfo, "Property can't be null");
var getMethodInfo = propertyInfo.GetGetMethod();
if (null != getMethodInfo)
{
m_GetValueDelegate = (Func)Delegate.CreateDelegate(typeof(Func), getMethodInfo);
}
var setMethodInfo = propertyInfo.GetSetMethod();
if (null != setMethodInfo)
{
m_SetValueDelegate = (Action)Delegate.CreateDelegate(typeof(Action), setMethodInfo);
}
}
public object GetValue(object instance)
{
Guard.ArgumentNotNull(m_GetValueDelegate, "The Property doesn't have GetMethod");
return m_GetValueDelegate((T)instance);
}
public void SetValue(object instance, object newValue)
{
Guard.ArgumentNotNull(m_SetValueDelegate, "The Property doesn't have SetMethod");
m_SetValueDelegate((T)instance, (P)newValue);
}
}
///
/// Singleton, MemberAccessor used to accessing member of a object at runtime.
///
public class MemberAccessor : IMemberAccessor
{
#region Singleton
private MemberAccessor() { }
public static MemberAccessor Instance
{
get { return Nested.m_instance; }
}
private class Nested
{
static Nested() { }
internal static readonly MemberAccessor m_instance = new MemberAccessor();
}
#endregion
private static Dictionary m_accessorCache = new Dictionary();
///
/// Get the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The member value
public object GetValue(object instance, string memberName)
{
INamedMemberAccessor ma = FindAccessor(instance, memberName);
Guard.ArgumentNotNull(ma, "The instance doesn't have this property");
return ma.GetValue(instance);
}
///
/// Set the member value of an object.
///
/// The object to get the member value from.
/// The member name, could be the name of a property of field. Must be public member.
/// The new value of the property for the object instance.
public void SetValue(object instance, string memberName, object newValue)
{
INamedMemberAccessor ma = FindAccessor(instance, memberName);
Guard.ArgumentNotNull(ma, "The instance doesn't have this property");
ma.SetValue(instance, newValue);
}
private INamedMemberAccessor FindAccessor(object instance, string memberName)
{
Type type = instance.GetType();
string key = type.FullName + memberName;
INamedMemberAccessor accessor = null;
if (!m_accessorCache.TryGetValue(key, out accessor))
{
#region bug fix from Ambiguous Match Exception
PropertyInfo propInfo = type.GetProperty(memberName, BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance);
if (null == propInfo)
{
propInfo = type.GetProperty(memberName);
}
#endregion
if (null == propInfo)
{
return null;
}
else
{
accessor = Activator.CreateInstance(typeof(PropertyAccessor<,>).MakeGenericType(type, propInfo.PropertyType), propInfo) as INamedMemberAccessor;
m_accessorCache.Add(key, accessor);
}
}
return accessor;
}
}
}
C#代码
using System;
namespace XXX.Common
{
///
/// Common guard clauses
///
public static class Guard
{
///
/// Checks an argument to ensure it isn't null
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentNotNull(object argumentValue, string argumentName)
{
if (argumentValue == null)
{
throw new ArgumentNullException(argumentName);
}
}
}
}