我有以下方法,它在给定PropertyInfo
上设置给定的值TInstance
。这是为了避免反射效率低下。
public static Action<TInstance, object> CreateSetter<TInstance>(PropertyInfo propertyInfo, bool includeNonPublic = false)
{
var setMethod = propertyInfo.GetSetMethod(includeNonPublic);
var instance = Expression.Parameter(typeof(TInstance), "instance");
var value = Expression.Parameter(typeof(object), "value");
var valueCast = !propertyInfo.PropertyType.IsValueType
? Expression.TypeAs(value, propertyInfo.PropertyType)
: Expression.Convert(value, propertyInfo.PropertyType);
return Expression.Lambda<Action<TInstance, object>>(
Expression.Call(instance, setMethod, valueCast), instance, value).Compile();
}
所以给定以下模型:
public sealed class PersonClass
{
public string Name {get; set;}
}
我可以设置Name
使用:
var person = new PersonClass();
var nameProp = person.GetType().GetProperties().Where(p => p.Name == "Name").First();
var nameSetter = CreateSetter<PersonClass>(nameProp);
nameSetter(person, "Foo");
这一切都很好,但是如果我尝试使用struct
例如的方法:
public struct PersonStruct
{
public string Name {get; set;}
}
名字永远是null
。我怀疑拳击/拆箱以某种方式咬我。
事实上,如果我在使用FastMember
时使用相同的行为表现:
PersonStruct person = new PersonStruct();
var accessor = TypeAccessor.Create(person.GetType());
accessor[person, "Name"] = "Foo";
但是,当我将person
as装箱时,object
便FastMember
能够正确设置该值:
object person = new PersonStruct();
var accessor = TypeAccessor.Create(person.GetType());
accessor[person, "Name"] = "Foo";
有什么想法可以在CreateSetter
for whenTInstance
是值类型时处理这个拳击吗?