Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按名称调用属性_C#_Reflection - Fatal编程技术网

C# 按名称调用属性

C# 按名称调用属性,c#,reflection,C#,Reflection,我有一个类,它有100多个唯一命名的属性和20多个子类,有时在列表中。下面是我的意思的一个大大简化的说明: public class classA { public String PropertyA1 { get; set; } public int PropertyA2{get;set;} public List<classB> myList; public classC myClass { get; set;

我有一个类,它有100多个唯一命名的属性和20多个子类,有时在列表中。下面是我的意思的一个大大简化的说明:

public class classA
    {
        public String PropertyA1 { get; set; }
        public int PropertyA2{get;set;}
        public List<classB> myList;
        public classC myClass { get; set; }

        public void SetProperty(String PropertyName)
        {
            // Match property name to property in this class or child class.
        }
    }

    class classB
    {
        public String PropertyB1 { get; set; }
        public bool PropertyB2 { get; set; }
    }

    class classC
    {
        public String PropertyC1 { get; set; }
    }
公共类classA
{
公共字符串PropertyA1{get;set;}
公共int属性ya2{get;set;}
公开名单;
公共类C myClass{get;set;}
公共void SetProperty(字符串PropertyName)
{
//将属性名称与此类或子类中的属性匹配。
}
}
B类
{
公共字符串PropertyB1{get;set;}
公共bool属性b2{get;set;}
}
C类
{
公共字符串PropertyC1{get;set;}
}
我想做两件事,这可能是可能的,也可能是不可能的。我需要做的第一件事是迭代每个公共属性,包括子类和列表中的类,并转换这些值。我知道我可以通过序列化为xml并解析结果来完成解析。我甚至已经准备好了转换为xml的代码,因为该类的功能是构建一个xml对象。但是,我担心通过xml解析可能比通过反射访问属性要昂贵得多。反射可以以这种方式使用吗?它会比修改xml更快吗


我想做的另一件事是访问将属性名传递到方法中的任何属性。我意识到我需要一个单独的方法来访问列表中的类,并且可能需要将列表转换为字典。问题是,这是否可能,代码是否只需要在父类中,或者每个子类是否需要重复代码?

方法将使用给定名称设置属性:

    public void SetProperty(String propertyName, object value)
    {
        this.GetType().GetProperty(propertyName).SetValue(this, value);
    }
有关实施的一些事项:

  • 使用的类型是对象的动态实际类型,它将查找派生类中的成员(当然,只要对象是派生类型)
  • 属性信息不知道它来自哪个对象,因此必须将此
    再次传递给
    SetValue()
    调用
问题的第二部分是迭代属性列表,可以通过使用
GetProperties()
获取对象的所有属性(包括继承的属性)来解决:

var properties = this.GetType().GetProperties();

听起来你需要反省一下。首先看一下
Type.GetProperty
Type.GetProperties
。您试图通过反射来完成的事情是可能的,但是我们想看看您到目前为止在尝试实现这一点时学到了什么,以及您在哪里学习XML序列化程序使用反射来生成XML文档。我想你会发现反射更快,“我有一个类,它有100多个唯一命名的属性和20多个子类”。哦,我真可怜你。那么你有两组对象,一组用于使用源XML,另一组用于序列化,以及从一组到另一组的映射?Automapper不适用于您?您可以将其作为泛型扩展,这样就不必在每个类层次结构中粘贴该方法。感谢Anders的回复。我相信这对基类有效,但是我能在classA中设置调用此方法的PropertyC1的值吗?@Jay:
SetProperty
方法应该是基类的成员。不要让它成为一个扩展,这将使它可以在更多的地方使用。它很难看,所以让我们只把它放在需要的地方。@Tim:是的,只要对象是
ClassC
的实例,它就能够设置
PropertyC1
,即使方法是在
ClassA
中定义的,因为该方法通过
this.GetType()使用对象的实际类型
而不是基类类型。我仍然认为这里的扩展更好。因为现在所有的类都必须从同一个基继承,这可能是不需要的。您至少可以创建一个接口
IPropertySetable
,并对其进行扩展。