답변:
예, 다음을 사용할 수 있습니다 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);
}
obj.GetType().GetProperty("Name")?.GetSetMethod()?.Invoke(...)
CanWrite=False유형에 대한 가치를 설정하는 것이 불가능 합니까?
당신은 또한 할 수 있습니다 :
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);
}
다음과 같은 것을 사용하십시오 :
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);
}
}
속성 이름을 사용하여 다른 개체에서 개체의 속성을 대량 할당하려는 경우이 기능을 사용해 볼 수 있습니다.
public static void Assign(this object destination, object source)
{
if (destination is IEnumerable && source is IEnumerable)
{
var dest_enumerator = (destination as IEnumerable).GetEnumerator();
var src_enumerator = (source as IEnumerable).GetEnumerator();
while (dest_enumerator.MoveNext() && src_enumerator.MoveNext())
dest_enumerator.Current.Assign(src_enumerator.Current);
}
else
{
var destProperties = destination.GetType().GetProperties();
foreach (var sourceProperty in source.GetType().GetProperties())
{
foreach (var destProperty in destProperties)
{
if (destProperty.Name == sourceProperty.Name && destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
{
destProperty.SetValue(destination, sourceProperty.GetValue(source, new object[] { }), new object[] { });
break;
}
}
}
}
방금 첫 번째 수준의 속성뿐만 아니라 주어진 객체에 중첩 속성을 설정할 수있는 Nuget 패키지를 방금 게시했습니다.
여기 패키지가 있습니다
루트에서 경로로 객체의 속성 값을 설정합니다.
개체는 복잡한 개체 일 수 있으며 속성은 다중 수준의 딥 중첩 속성이거나 루트 바로 아래에있는 속성 일 수 있습니다. ObjectWriter속성 경로 매개 변수를 사용하여 속성을 찾고 값을 업데이트합니다. 속성 경로는 루트에서 우리가 설정하려는 끝 노드 속성까지 방문한 속성의 추가 된 이름으로 구분자 문자열 매개 변수로 구분됩니다.
용법:
오브젝트 루트 바로 아래에 특성을 설정하려면 다음을 수행하십시오.
즉. LineItem클래스에는라는 int 속성이 있습니다ItemId
LineItem lineItem = new LineItem();
ObjectWriter.Set(lineItem, "ItemId", 13, delimiter: null);
객체 루트 아래에 여러 수준의 중첩 속성을 설정하려면 다음을 수행하십시오.
즉. Inviteclass에는이라는 속성 State이 있으며,이 속성에는 Invite(초대 유형)이라는 속성 Recipient이 있으며, 속성에는 속성이 Id있습니다.
일을 더욱 복잡하게하기 위해이 State속성은 참조 유형이 아닙니다 struct.
개체 트리의 맨 아래에 Id 속성 (문자열 값 "Outlook")을 한 줄로 설정하는 방법은 다음과 같습니다.
Invite invite = new Invite();
ObjectWriter.Set(invite, "State_Invite_Recipient_Id", "outlook", delimiter: "_");
MarcGravell의 제안에 따라 다음과 같은 정적 메소드를 구성했습니다.이 메소드는 일반적으로 FastMember를 사용하여 소스 객체에서 대상으로 일치하는 모든 속성을 할당합니다.
public static void DynamicPropertySet(object source, object target)
{
//SOURCE
var src_accessor = TypeAccessor.Create(source.GetType());
if (src_accessor == null)
{
throw new ApplicationException("Could not create accessor!");
}
var src_members = src_accessor.GetMembers();
if (src_members == null)
{
throw new ApplicationException("Could not fetch members!");
}
var src_class_members = src_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
var src_class_propNames = src_class_members.Select(x => x.Name);
var src_propNames = src_members.Except(src_class_members).Select(x => x.Name);
//TARGET
var trg_accessor = TypeAccessor.Create(target.GetType());
if (trg_accessor == null)
{
throw new ApplicationException("Could not create accessor!");
}
var trg_members = trg_accessor.GetMembers();
if (trg_members == null)
{
throw new ApplicationException("Could not create accessor!");
}
var trg_class_members = trg_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
var trg_class_propNames = trg_class_members.Select(x => x.Name);
var trg_propNames = trg_members.Except(trg_class_members).Select(x => x.Name);
var class_propNames = trg_class_propNames.Intersect(src_class_propNames);
var propNames = trg_propNames.Intersect(src_propNames);
foreach (var propName in propNames)
{
trg_accessor[target, propName] = src_accessor[source, propName];
}
foreach (var member in class_propNames)
{
var src = src_accessor[source, member];
var trg = trg_accessor[target, member];
if (src != null && trg != null)
{
DynamicPropertySet(src, trg);
}
}
}
var val = Convert.ChangeType(propValue, propInfo.PropertyType);source : devx.com/vb2themax/Tip/19599