[c#] 리플렉션을 사용하여 객체 속성 설정

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)

리플렉션을 통해 모든 것이 열린 책이 될 수 있습니다.) 내 예제에서는 개인 인스턴스 레벨 필드에 바인딩합니다.