【问题标题】:Iterate all properties of an aggregate class and instantiate?迭代聚合类的所有属性并实例化?
【发布时间】:2015-12-19 18:45:16
【问题描述】:

关于如何遍历类的所有属性,有各种非常棒的信息。然而,我想要做的是遍历它们并将每个属性实例化为构造函数中的新属性......该类是一个聚合类,表示实体框架模型对象/类的集合。我可以依次实例化每一个,但是当我决定向数据库添加另一个表时,这将是一个巨大的维护问题......

public class ClsAggModel {
    public ClsAggModel() {
        foreach (PropertyInfo props in this.GetType().GetProperties()) {
            props.SetValue = new props.GetType(); //problem here!
        }
    }

   public clsItem1 pProp1{ get; set; }
   public clsItem2 pProp2{ get; set; }
   //...and so on

问题在于编译器此时似乎不知道props 是什么:

找不到类型或命名空间名称“props”(您是否缺少 using 指令还是程序集引用?)

这似乎有点奇怪,因为我只是在循环签名中证明了它。我可以填写每个属性并做私有变量和所有那些爵士乐,但如果你不能滥用反射有什么好处?

有什么建议吗?

【问题讨论】:

    标签: c#


    【解决方案1】:

    您不能以这种方式在.GetType() 的基础上创建实例。

    这不起作用:

    new props.GetType();
    

    您应该尝试使用:

    Activator.CreateInstance(props.GetType());
    

    【讨论】:

    • No parameterless constructor defined for this object.需要第二个参数:一个值
    【解决方案2】:

    根据已经提供的解决方案,您的代码应如下所示:

    public class ClsAggModel {
        public ClsAggModel() {
            foreach (PropertyInfo prop in this.GetType().GetProperties()) {
                var newValue = Activator.CreateInstance(prop.GetType());
                prop.SetValue(this, newValue);
            }
        }
    
       public clsItem1 pProp1{ get; set; }
       public clsItem2 pProp2{ get; set; }
    

    请记住,所有属性类型都必须允许动态创建,方法是提供默认构造函数(如果未定义其他构造函数,它会自动存在)。

    【讨论】:

    • No parameterless constructor defined for this object on Activator.CreateInstance 这些是 ClsAggModel 中的模型优先 EF 类。我可以将每个类扩展为部分并处理构造函数,但这违背了迭代的目的。
    • 您能否向我们提供引发此错误的属性类型?遍历“所有”属性可能会得到一些不需要的属性。据我所知,如果类没有扩展,模型优先实体应该只有默认构造函数。
    • 这是一个聚合类,其中每个属性都是一个实体框架模型。例如,pAccount 将是一个包含帐户表的模型优先实体框架类account 的属性。该对象本身就像模型优先的 EF 对象一样,是基本类型(如字符串、int 等)的属性的集合。在调试时,prop.GetType() 的监视窗口名称返回 prop.GetType() {Name = "RuntimePropertyInfo" FullName = "System.Reflection.RuntimePropertyInfo"} System.Type {System.RuntimeType} 这顺便说一句,不是一些“意外”属性。
    • 我想知道 prop.PropertyType 和 prop.Name(不是 PropertyInfo 类型的属性)什么时候抛出异常。
    • PropertyType 是 prop.PropertyType {Name = "account" FullName = "WCF_Tracker_Library.account"} System.Type {System.RuntimeType} 名称是:“pAccount”。就像我说的,一个实体框架对象,因为我正在迭代其属性的类是 EF 对象的聚合类。
    【解决方案3】:

    假设您要调用默认创建的类型,请像这样使用激活器

    props.SetValue(this, Activator.CreateInstance(props.GetType()));
    

    注意,如果没有默认构造函数,这仍然会失败。因为您正在使用反射,所以您的编译器无法再检查这一点。

    注意 2:滥用反射时要小心变化。这是迟早要在脚上开枪的肯定方法。

    更新当然setvalue是一个方法,改了这个

    【讨论】:

    • Hrm,SetValue 是一种方法,因此 .SetValue(Activator...) 但它需要第二个参数,所以我仍然遇到同样的问题,并通过 null 踢球和咯咯笑让我 No parameterless constructor defined for this object.
    • props.SetValue = ... 应该是props.SetValue(this, Activator.CreateInstance(props.GetType())
    • 您应该为每个要为其创建类的类添加一个默认的空构造函数。
    • 一个默认的构造函数或者确保根本没有构造函数,并且会创建一个默认值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 2020-11-25
    • 2020-07-09
    • 2016-03-31
    • 1970-01-01
    相关资源
    最近更新 更多