하고 사용하기가 좀 더 쉽게 만들 : 그것은 다른 사람이 같은 문제를 가지고 도움이 될 나는이 블로그 게시물에서 조각을 추가했습니다. DynamicCast 기능이 도입되어 사용자의 유형을 알 필요가 있으므로 이상적이지 않습니다. 내 목표는 우리를 강하게 입력하고 객체를 반환하지 않고 동적 키워드를 사용하지 않으려 고 노력하는 것이 었습니다. 또한 "마법"을 최소한으로 유지하십시오.
public static T DynamicCast<T>(this object value)
{
return (T) value;
}
public static object GetPropertyValue<T>(this PropertyInfo propertyInfo, T objectInstance)
{
if (typeof(T) != propertyInfo.DeclaringType)
{
throw new ArgumentException();
}
var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
var property = Expression.Property(instance, propertyInfo);
var convert = Expression.TypeAs(property, propertyInfo.PropertyType);
var lambda = Expression.Lambda(convert, instance).Compile();
var result = lambda.DynamicInvoke(objectInstance);
return result;
}
public static void SetPropertyValue<T, TP>(this PropertyInfo propertyInfo, T objectInstance, TP value)
where T : class
where TP : class
{
if (typeof(T) != propertyInfo.DeclaringType)
{
throw new ArgumentException();
}
var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
var argument = Expression.Parameter(propertyInfo.PropertyType, "a");
var setterCall = Expression.Call(
instance,
propertyInfo.GetSetMethod(),
Expression.Convert(argument, propertyInfo.PropertyType));
var lambda = Expression.Lambda(setterCall, instance, argument).Compile();
lambda.DynamicInvoke(objectInstance, value);
}
예 :
public void Get_Value_Of_Property()
{
var testObject = new ReflectedType
{
AReferenceType_No_Attributes = new object(),
Int32WithRange1_10 = 5,
String_Requires = "Test String"
};
var result = testObject.GetType().GetProperty("String_Requires").GetPropertyValue(testObject).DynamicCast<string>();
result.Should().Be(testObject.String_Requires);
}
public void Set_Value_Of_Property()
{
var testObject = new ReflectedType
{
AReferenceType_No_Attributes = new object(),
Int32WithRange1_10 = 5,
String_Requires = "Test String"
};
testObject.GetType().GetProperty("String_Requires").SetPropertyValue(testObject, "MAGIC");
testObject.String_Requires.Should().Be("MAGIC");
}
당신 람다는 PropertyInfo 오브젝트를 기반에서는 dynamicCast를 호출하는 것을 피하기 위해 입력 된 전화를 할 수 있도록하기 위해 MakeGenericMethod 또는 식 트리를 사용하는 도우미 메서드를 작성할 수 그것을 알기 위해. 하지만 덜 우아합니다.
목표는 무엇입니까? 당신은 람다 식을 만들고 싶다고 말합니다. 컴파일 된 델리게이트 ('functionThatGetsValue') 만 필요합니까, 아니면 중간 표현식 트리 ('expression')도 필요합니까? – LukeH
@LukeH, 그냥 컴파일 된 대리자. 감사. (목표는 객체 목록을 반복하여 속성에서 모든 값을 읽는 것입니다. 약간의 성능을 얻으려면 리플렉션을 사용하는 대신이 방법으로 수행하고 싶습니다.) – gsharp
비슷한 결과를 얻으려고하면 Func를 반환하고 호출자 측의 특정 속성 유형으로 반환 값을 캐스팅합니다. –