Created
April 8, 2012 18:54
-
-
Save jwatney/2339182 to your computer and use it in GitHub Desktop.
Fast Property Info-type class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
namespace TypeUtil { | |
public static class TypeExtensions { | |
public static FastPropertyInfo<T> GetProperty<T>(this Type type, string name) { | |
return type.GetProperty<T>(name, BindingFlags.Default); | |
} | |
public static FastPropertyInfo<T> GetProperty<T>(this Type type, string name, BindingFlags flags) { | |
var property = type.GetProperty(name, flags); | |
if(property == null) { | |
return null; | |
} | |
return new FastPropertyInfo<T>(property); | |
} | |
} | |
public class FastPropertyInfo<T> { | |
private PropertyInfo info; | |
private Func<T, object[], object> getter; | |
private Action<T, object, object[]> setter; | |
public bool CanRead { get { return info.CanRead; } } | |
public bool CanWrite { get { return info.CanWrite; } } | |
public FastPropertyInfo(PropertyInfo info) { | |
this.info = info; | |
getter = CreateGetValue(info); | |
setter = CreateSetValue(info); | |
} | |
public object GetValue(T instance, object[] index) { | |
if(getter == null) { | |
throw new ArgumentException("The property's get accessor is not found."); | |
} | |
return getter(instance, index); | |
} | |
public void SetValue(T instance, object value, object[] index) { | |
if(setter == null) { | |
throw new ArgumentException("The property's set accessor is not found."); | |
} | |
setter(instance, value, index); | |
} | |
private static Func<T, object[], object> CreateGetValue(PropertyInfo info) { | |
if(!info.CanRead) { | |
return null; | |
} | |
// info.GetValue(instance, null); | |
var instanceExpression = Expression.Parameter(typeof(T), "instance"); | |
var indexExpression = Expression.Parameter(typeof(object[]), "index"); | |
var getExpression = Expression.Call(instanceExpression, info.GetGetMethod()); | |
var lambdaExpression = Expression.Lambda<Func<T, object[], object>>(Expression.Convert(getExpression, typeof(object)), instanceExpression, indexExpression); | |
return lambdaExpression.Compile(); | |
} | |
private static Action<T, object, object[]> CreateSetValue(PropertyInfo info) { | |
if(!info.CanWrite) { | |
return null; | |
} | |
// info.SetValue(instance, value, null); | |
var valueType = info.GetSetMethod().GetParameters()[0].ParameterType; | |
var instanceExpression = Expression.Parameter(typeof(T), "instance"); | |
var valueExpression = Expression.Parameter(valueType, "value"); | |
var indexExpression = Expression.Parameter(typeof(object[]), "index"); | |
var setExpression = Expression.Call(instanceExpression, info.GetSetMethod(), valueExpression, indexExpression); | |
var lambdaExpression = Expression.Lambda<Action<T, object, object[]>>(setExpression, instanceExpression, valueExpression, indexExpression); | |
return lambdaExpression.Compile(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment