繁体   English   中英

c#递归反射和通用列表设置默认属性

[英]c# Recursive Reflection & Generic Lists setting default properties

我试图使用反射来实现以下目的:

我需要一个方法,我传入一个对象,这个方法将递归实例化具有子对象的对象,并使用默认值设置属性。 我需要实例化整个对象,根据需要进行多个级别。

此方法需要能够处理具有多个属性的对象,这些属性将是其他对象的通用列表。

这是我的示例代码(当我得到一个包含List<AnotherSetObjects>的对象时,我得到一个参数计数不匹配异常:

private void SetPropertyValues(object obj)
{
    PropertyInfo[] properties = obj.GetType().GetProperties();

    foreach (PropertyInfo property in properties)
    {
        if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && property.PropertyType.FullName.Contains("BusinessObjects"))
        {
            Type propType = property.PropertyType;

            var subObject = Activator.CreateInstance(propType);
            SetPropertyValues(subObject);
            property.SetValue(obj, subObject, null);
        }
        else if (property.PropertyType == typeof(string))
        {
            property.SetValue(obj, property.Name, null);
        }
        else if (property.PropertyType == typeof(DateTime))
        {
            property.SetValue(obj, DateTime.Today, null);
        }
        else if (property.PropertyType == typeof(int))
        {
            property.SetValue(obj, 0, null);
        }
        else if (property.PropertyType == typeof(decimal))
        {
            property.SetValue(obj, 0, null);
        }
    }
}

谢谢

您可以通过检查property.PropertyType.IsGeneric来筛选出来,这对于通用容器是真的。 如果需要,还要检查property.PropertyType.IsArray

此外,您可能还想避免使用非通用容器。 在这种情况下,测试对象是否是这种容器的接口类型。 例如 - IList

bool isList(object data)
{
    System.Collections.IList list = data as System.Collections.IList;
    return list != null;
}

...
if (isList(obj)) {
    //do stuff that take special care of object which is a List
    //It will be true for generic type lists too!
}

这是一个棘手的:)

当您将包含某些“BusinessObjects”类型的通用列表的对象作为属性传递给初始化程序时,此属性将通过您的属性

if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && property.PropertyType.FullName.Contains("BusinessObjects"))

表达式,因为实例化的泛型类型将具有如下名称:

System.Collections.Generic.List`1[[ConsoleApplication92.XXXBusinessObjects, ConsoleApplication92, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

这导致使用List本身作为参数调用初始化方法。 该列表将有一个名为Item的SomeBusinessObjects类型的索引器。 这也将通过上述条件,因此您也会尝试初始化它。 它的结果是这样的:

obj.ListProperty.Item = new SomeBusinessObject();

而索引器只能在这样的初始化中使用

obj.ListProperty[0] = new SomeBusinessObject();

这表明,确实,你缺少一个参数。

你要做的就是取决于你:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM