Это решение использует деревья выражений, поскольку их довольно легко составлять, и они предоставляют удобный метод Compile () для получения фактического Делегата, к которому вы можете обращаться.Я сделал Func на самом деле взять объект (так что Funcа не просто Func ), поэтому вы можете получить значение свойства из любого экземпляра.
Редактировать : также добавлена реализация установки.
public class MyClass
{
public string MyStringProperty { get; set; }
}
class Program
{
static void Main(string[] args)
{
PropertyInfo propertyInfo = typeof(MyClass).GetProperty("MyStringProperty");
Delegate getter = CreateGetter(propertyInfo);
Delegate setter = CreateSetter(propertyInfo);
object myClass = new MyClass();
setter.DynamicInvoke(myClass, "Hello");
Console.WriteLine(getter.DynamicInvoke(myClass));
}
public static Delegate CreateGetter(PropertyInfo property)
{
var objParm = Expression.Parameter(property.DeclaringType, "o");
Type delegateType = typeof(Func<,>).MakeGenericType(property.DeclaringType, property.PropertyType);
var lambda = Expression.Lambda(delegateType, Expression.Property(objParm, property.Name), objParm);
return lambda.Compile();
}
public static Delegate CreateSetter(PropertyInfo property)
{
var objParm = Expression.Parameter(property.DeclaringType, "o");
var valueParm = Expression.Parameter(property.PropertyType, "value");
Type delegateType = typeof(Action<,>).MakeGenericType(property.DeclaringType, property.PropertyType);
var lambda = Expression.Lambda(delegateType, Expression.Assign(Expression.Property(objParm, property.Name), valueParm), objParm, valueParm);
return lambda.Compile();
}
}
Распечатывает «Hello», сначала используя динамический установщик, чтобы установить его в «Hello», а затем используядинамический геттер для получения свойства от объекта.