未知对象中的C#Set属性

未知对象中的C#Set属性,c#,class,object,reflection,gettype,C#,Class,Object,Reflection,Gettype,我必须在未知对象中设置属性。结构如下所示: ObjA.ObjB().ObjC.PropA = propValue; ObjA来自引用的类。ObjB()属于object类型,因此ObjC未知。我考虑过使用反射,但不知道如何在这种情况下正确使用它 object objB = ObjA.ObjB(); Type objBType = objB.GetType(); System.Reflection.XXXInfo objCInfo =

我必须在未知对象中设置属性。结构如下所示:

        ObjA.ObjB().ObjC.PropA = propValue;
ObjA来自引用的类。ObjB()属于object类型,因此ObjC未知。我考虑过使用反射,但不知道如何在这种情况下正确使用它

        object objB = ObjA.ObjB();
        Type objBType = objB.GetType();
        System.Reflection.XXXInfo objCInfo = objBType.GetXXX("ObjC");

        Type objCType = objCInfo.GetType();
        System.Reflection.PropertyInfo PropAInfo = objCType.GetProperty("PropA");
        PropAInfo.SetValue(PropAInfo, propValue, null);
回答(感谢BigM):


这可能对你有用

object objB = ObjA.ObjB();
Type objBType = objB.GetType();
System.Reflection.PropertyInfo objCInfo = objBType.GetProperty("ObjC");
object val = objCInfo.GetValue(objB);

Type objCType = val.GetType();
System.Reflection.PropertyInfo PropAInfo = objCType.GetProperty("PropA");
PropAInfo.SetValue(val, propValue, null);
然而,我认为可以在这里进行一些重新设计,使生活更轻松。例如,如果您不知道关于类型的<强>任何< /强>,那么您可以考虑使用<代码>动态< /代码>,并从<代码> Objc和<代码> PROP< <代码>中返回<代码>动态< /代码>类型,但是在那里有一个性能命中。
另一方面,如果有任何方法可以使用泛型,那将使您的生活变得更加轻松。例如,这里设置属性值的代码,如果该方法是泛型的,那么它可能能够定义
ObjC
的类型,但我不能用当前代码段真正推断出这一点。

这可能适用于您

object objB = ObjA.ObjB();
Type objBType = objB.GetType();
System.Reflection.PropertyInfo objCInfo = objBType.GetProperty("ObjC");
object val = objCInfo.GetValue(objB);

Type objCType = val.GetType();
System.Reflection.PropertyInfo PropAInfo = objCType.GetProperty("PropA");
PropAInfo.SetValue(val, propValue, null);
然而,我认为可以在这里进行一些重新设计,使生活更轻松。例如,如果您不知道关于类型的<强>任何< /强>,那么您可以考虑使用<代码>动态< /代码>,并从<代码> Objc和<代码> PROP< <代码>中返回<代码>动态< /代码>类型,但是在那里有一个性能命中。
另一方面,如果有任何方法可以使用泛型,那将使您的生活变得更加轻松。例如,此处设置属性值的代码,如果该方法是泛型的,则它可能能够定义
ObjC
的类型,但我无法用当前代码段真正推断出这一点。

以下是一些泛型扩展方法,可帮助您按名称获取和设置“未知”属性:

公共静态类ReflectionHelpers
{
公共静态bool TrySetProperty(此对象对象对象、字符串属性名称、TValue值)
{
var property=obj.GetType()
.GetProperties()
.Where(p=>p.CanWrite&&p.PropertyType==typeof(TValue))
.FirstOrDefault(p=>p.Name==propertyName);
if(属性==null)
{
返回false;
}
属性设置值(obj,值);
返回true;
}
公共静态bool TryGetPropertyValue(此对象对象obj,字符串propertyName,out TProperty值)
{
var property=obj.GetType()
.GetProperties()
.Where(p=>p.CanRead&&p.PropertyType==typeof(TProperty))
.FirstOrDefault(p=>p.Name==propertyName);
if(属性==null)
{
值=默认值(TProperty);
返回false;
}
value=(TProperty)property.GetValue(obj);
返回true;
}
}
以及一个使用示例:

公共类程序
{
公共静态void Main()
{
var foo=新foo
{
酒吧=新酒吧
{
HelloReflection=“测试”
}
};
字符串当前值;
if(foo.Bar.TryGetPropertyValue(“HelloReflection”,out currentValue))
{
Console.WriteLine(currentValue);/“测试”
}
if(foo.Bar.TrySetProperty(“HelloReflection”、“123…”)
{
foo.Bar.TryGetPropertyValue(“HelloReflection”,out currentValue)
Console.WriteLine(当前值);/“123..”
}
其他的
{
Console.WriteLine(“设置值失败”);
}
}
}
公开课Foo
{
公共对象栏{get;set;}
}
公共类酒吧
{
公共字符串HelloReflection{get;set;}
}

以下是一些通用扩展方法,可帮助您按名称获取和设置“未知”属性:

公共静态类ReflectionHelpers
{
公共静态bool TrySetProperty(此对象对象对象、字符串属性名称、TValue值)
{
var property=obj.GetType()
.GetProperties()
.Where(p=>p.CanWrite&&p.PropertyType==typeof(TValue))
.FirstOrDefault(p=>p.Name==propertyName);
if(属性==null)
{
返回false;
}
属性设置值(obj,值);
返回true;
}
公共静态bool TryGetPropertyValue(此对象对象obj,字符串propertyName,out TProperty值)
{
var property=obj.GetType()
.GetProperties()
.Where(p=>p.CanRead&&p.PropertyType==typeof(TProperty))
.FirstOrDefault(p=>p.Name==propertyName);
if(属性==null)
{
值=默认值(TProperty);
返回false;
}
value=(TProperty)property.GetValue(obj);
返回true;
}
}
以及一个使用示例:

公共类程序
{
公共静态void Main()
{
var foo=新foo
{
酒吧=新酒吧
{
HelloReflection=“测试”
}
};
字符串当前值;
if(foo.Bar.TryGetPropertyValue(“HelloReflection”,out currentValue))
{
Console.WriteLine(currentValue);/“测试”
}
if(foo.Bar.TrySetProperty(“HelloReflection”、“123…”)
{
foo.Bar.TryGetPropertyValue(“HelloReflection”,out currentValue)
Console.WriteLine(当前值);/“123..”
}
其他的
{
Console.WriteLine(“设置值失败”);
}
}
}
公开课Foo
{
公共对象栏{get;set;}
}
公共类酒吧
{
公共字符串HelloReflection{get;set;}
}

您不能重构它以创建公共接口或基类吗?它将更易于维护和故障防护;不工作?你不能重构它来创建一个公共接口或基类吗?它将更易于维护和故障防护;不起作用吗