C #에서 리플렉션을 사용하여 객체 속성을 설정할 수있는 방법이 있습니까?
전의:
MyObject obj = new MyObject();
obj.Name = "Value";
obj.Name
반사 로 설정하고 싶습니다 . 다음과 같은 것 :
Reflection.SetProperty(obj, "Name") = "Value";
이 방법이 있습니까?
답변
예, 다음을 사용할 수 있습니다 Type.InvokeMember()
.
using System.Reflection;
MyObject obj = new MyObject();
obj.GetType().InvokeMember("Name",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, obj, "Value");
obj
이라는 속성 Name
이 없거나 설정할 수없는 경우 예외가 발생합니다 .
또 다른 방법은 속성의 메타 데이터를 가져 와서 설정하는 것입니다. 이를 통해 속성의 존재를 확인하고 설정할 수 있는지 확인할 수 있습니다.
using System.Reflection;
MyObject obj = new MyObject();
PropertyInfo prop = obj.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
if(null != prop && prop.CanWrite)
{
prop.SetValue(obj, "Value", null);
}
답변
당신은 또한 할 수 있습니다 :
Type type = target.GetType();
PropertyInfo prop = type.GetProperty("propertyName");
prop.SetValue (target, propertyValue, null);
여기서 target은 속성이 설정 될 객체입니다.
답변
반사, 기본적으로, 즉
myObject.GetType().GetProperty(property).SetValue(myObject, "Bob", null);
또는 편의성과 성능 측면에서 모두 도움이되는 라이브러리가 있습니다. 예를 들어 FastMember :
var wrapped = ObjectAccessor.Create(obj);
wrapped[property] = "Bob";
(또한 필드 대 속성인지 사전에 알 필요가 없다는 이점이 있습니다)
답변
또는 Marc의 하나의 라이너를 자신의 확장 클래스 안에 넣을 수 있습니다.
public static class PropertyExtension{
public static void SetPropertyValue(this object obj, string propName, object value)
{
obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}
}
다음과 같이 호출하십시오.
myObject.SetPropertyValue("myProperty", "myValue");
좋은 측정을 위해 속성 값을 얻는 방법을 추가해 보겠습니다.
public static object GetPropertyValue(this object obj, string propName)
{
return obj.GetType().GetProperty(propName).GetValue (obj, null);
}
답변
예, 다음을 사용합니다 System.Reflection
.
using System.Reflection;
...
string prop = "name";
PropertyInfo pi = myObject.GetType().GetProperty(prop);
pi.SetValue(myObject, "Bob", null);
답변
다음과 같은 것을 사용하십시오 :
public static class PropertyExtension{
public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
{
PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
property.SetValue(p_object, Convert.ChangeType(value, property.PropertyType), null);
}
}
또는
public static class PropertyExtension{
public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
{
PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
object safeValue = (value == null) ? null : Convert.ChangeType(value, t);
property.SetValue(p_object, safeValue, null);
}
}
답변
비슷한 방식으로 필드에 액세스 할 수도 있습니다.
var obj=new MyObject();
FieldInfo fi = obj.GetType().
GetField("Name", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(obj,value)
리플렉션을 통해 모든 것이 열린 책이 될 수 있습니다.) 내 예제에서는 개인 인스턴스 레벨 필드에 바인딩합니다.