代码可以直接拿来用参考文章:https://www.cnblogs.com/xinaixia/p/5777886.html
class Program
{
static void Main(string[] args)
{
ReflectionExample(10000);
DelegateExample(10000);
DelgateCacheExample(10000);
Console.ReadKey();
}
static void DelgateCacheExample(int count)
{
var bt = DateTime.Now.Ticks;
var propertyIdInfo = typeof(Test).GetProperty("Id");
var propertyNameInfo = typeof(Test).GetProperty("Name");
var propertyTTInfo = typeof(Test).GetProperty("TT");
var tests = Enumerable.Repeat(new Test(), count).ToList();
foreach (var test in tests)
{
propertyIdInfo.FastSetValue(test, 1);
propertyNameInfo.FastSetValue(test, "jeffcky");
propertyTTInfo.FastSetValue(test, "TT");
}
var et = DateTime.Now.Ticks;
var ret = et - bt;
Console.WriteLine($"Id={tests[count - 1].Id},Name={tests[count - 1].Name},TT= {Test.TT}");
Console.WriteLine($"委托泛型缓存赋值耗时:{ret / TimeSpan.TicksPerMillisecond}ms");
}
static void ReflectionExample(int count)
{
var bt = DateTime.Now.Ticks;
var tests = Enumerable.Repeat(new Test(), count).ToList();
var propertyIdInfo = typeof(Test).GetProperty("Id");
var propertyNameInfo = typeof(Test).GetProperty("Name");
var propertyTTInfo = typeof(Test).GetProperty("TT");
foreach (var test in tests)
{
propertyIdInfo.SetValue(test, 1);
propertyNameInfo.SetValue(test, "jeffcky");
propertyTTInfo.SetValue(test, "TT");
}
var et = DateTime.Now.Ticks;
var ret = et - bt;
Console.WriteLine($"Id={tests[count - 1].Id},Name={tests[count - 1].Name},TT= {Test.TT}");
Console.WriteLine($"反射赋值耗时:{ret / TimeSpan.TicksPerMillisecond}ms");
}
static void DelegateExample(int count)
{
var bt = DateTime.Now.Ticks;
var tests = Enumerable.Repeat(new Test(), count).ToList();
var setId = (Action<Test, int>)Delegate.CreateDelegate(typeof(Action<Test, int>), null,
typeof(Test).GetProperty("Id").GetSetMethod());
var setName = (Action<Test, string>)Delegate.CreateDelegate(typeof(Action<Test, string>), null,
typeof(Test).GetProperty("Name").GetSetMethod());
var setTT = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), null,
typeof(Test).GetProperty("TT").GetSetMethod(true));
foreach (var test in tests)
{
setId(test, 3);
setName(test, "jeffcky");
setTT("TT");
}
var et = DateTime.Now.Ticks;
var ret = et - bt;
Console.WriteLine($"Id={tests[count - 1].Id},Name={tests[count - 1].Name},TT= {Test.TT}");
Console.WriteLine($"委托赋值耗时:{ret / TimeSpan.TicksPerMillisecond}ms");
}
public class Test
{
public string Name { get; set; }
public int Id { get; set; }
public static string TT { get; set; }
}
}
public static class GetterSetterFactory
{
private static readonly Hashtable s_getterDict = Hashtable.Synchronized(new Hashtable(10240));
private static readonly Hashtable s_setterDict = Hashtable.Synchronized(new Hashtable(10240));
internal static IGetValue GetPropertyGetterWrapper(PropertyInfo propertyInfo)
{
IGetValue property = (IGetValue)s_getterDict[propertyInfo];
if (property == null)
{
property = CreatePropertyGetterWrapper(propertyInfo);
s_getterDict[propertyInfo] = property;
}
return property;
}
internal static ISetValue GetPropertySetterWrapper(PropertyInfo propertyInfo)
{
ISetValue property = (ISetValue)s_setterDict[propertyInfo];
if (property == null)
{
property = CreatePropertySetterWrapper(propertyInfo);
s_setterDict[propertyInfo] = property;
}
return property;
}
public static IGetValue CreatePropertyGetterWrapper(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
if (propertyInfo.CanRead == false)
throw new InvalidOperationException("属性不支持读操作。");
MethodInfo mi = propertyInfo.GetGetMethod(true);
if (mi.GetParameters().Length > 0)
throw new NotSupportedException("不支持构造索引器属性的委托。");
if (mi.IsStatic)
{
Type instanceType = typeof(StaticGetterWrapper<>).MakeGenericType(propertyInfo.PropertyType);
return (IGetValue)Activator.CreateInstance(instanceType, propertyInfo);
}
else
{
Type instanceType = typeof(GetterWrapper<,>).MakeGenericType(propertyInfo.DeclaringType, propertyInfo.PropertyType);
return (IGetValue)Activator.CreateInstance(instanceType, propertyInfo);
}
}
public static ISetValue CreatePropertySetterWrapper(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
if (propertyInfo.CanWrite == false)
throw new NotSupportedException("属性不支持写操作。");
MethodInfo mi = propertyInfo.GetSetMethod(true);
if (mi.GetParameters().Length > 1)
throw new NotSupportedException("不支持构造索引器属性的委托。");
if (mi.IsStatic)
{
Type instanceType = typeof(StaticSetterWrapper<>).MakeGenericType(propertyInfo.PropertyType);
return (ISetValue)Activator.CreateInstance(instanceType, propertyInfo);
}
else
{
Type instanceType = typeof(SetterWrapper<,>).MakeGenericType(propertyInfo.DeclaringType, propertyInfo.PropertyType);
return (ISetValue)Activator.CreateInstance(instanceType, propertyInfo);
}
}
}
public class GetterWrapper<TTarget, TValue> : IGetValue
{
private Func<TTarget, TValue> _getter;
public GetterWrapper(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
if (propertyInfo.CanRead == false)
throw new InvalidOperationException("属性不支持读操作。");
MethodInfo m = propertyInfo.GetGetMethod(true);
_getter = (Func<TTarget, TValue>)Delegate.CreateDelegate(typeof(Func<TTarget, TValue>), null, m);
}
public TValue GetValue(TTarget target)
{
return _getter(target);
}
object IGetValue.Get(object target)
{
return _getter((TTarget)target);
}
}
public interface IGetValue
{
object Get(object target);
}
public interface ISetValue
{
void Set(object target, object val);
}
public static class PropertyExtensions
{
public static object FastGetValue(this PropertyInfo propertyInfo, object obj)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
return GetterSetterFactory.GetPropertyGetterWrapper(propertyInfo).Get(obj);
}
public static void FastSetValue(this PropertyInfo propertyInfo, object obj, object value)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
GetterSetterFactory.GetPropertySetterWrapper(propertyInfo).Set(obj, value);
}
}
public class SetterWrapper<TTarget, TValue> : ISetValue
{
private Action<TTarget, TValue> _setter;
public SetterWrapper(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
if (propertyInfo.CanWrite == false)
throw new NotSupportedException("属性不支持写操作。");
MethodInfo m = propertyInfo.GetSetMethod(true);
_setter = (Action<TTarget, TValue>)Delegate.CreateDelegate(typeof(Action<TTarget, TValue>), null, m);
}
public void SetValue(TTarget target, TValue val)
{
_setter(target, val);
}
void ISetValue.Set(object target, object val)
{
_setter((TTarget)target, (TValue)val);
}
}
public class StaticGetterWrapper<TValue> : IGetValue
{
private Func<TValue> _getter;
public StaticGetterWrapper(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
if (propertyInfo.CanRead == false)
throw new InvalidOperationException("属性不支持读操作。");
MethodInfo m = propertyInfo.GetGetMethod(true);
_getter = (Func<TValue>)Delegate.CreateDelegate(typeof(Func<TValue>), null, m);
}
public object Get(object target)
{
return _getter.Invoke();
}
}
public class StaticSetterWrapper<TValue> : ISetValue
{
private Action<TValue> _setter;
public StaticSetterWrapper(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
throw new ArgumentNullException("propertyInfo");
if (propertyInfo.CanWrite == false)
throw new NotSupportedException("属性不支持写操作。");
MethodInfo m = propertyInfo.GetSetMethod(true);
_setter = (Action<TValue>)Delegate.CreateDelegate(typeof(Action<TValue>), null, m);
}
public void Set(object target, object val)
{
_setter.Invoke((TValue)val);
}
}