如何递归调用分析属性的泛型方法

时间:2013-10-10 18:17:19

标签: c# generics reflection

我正在创建一个方法来分析我创建的类的实例,检查该类的每个属性是否为string类型,然后检查这些string属性是否为{ {1}}或空。

代码:

null

并非该类中的所有属性都是字符串,其中一些属于其他类的实例,这些类具有自己的属性,这些属性也需要以相同的方式进行分析。基本上,如果任何属性是在RootClass上具有值的字符串或类的子级别上的任何位置,则该方法将返回public class RootClass { public string RootString1 { get; set; } public string RootString2 { get; set; } public int RootInt1 { get; set; } public Level1ChildClass1 RootLevel1ChildClass11 { get; set; } public Level1ChildClass1 RootLevel1ChildClass12 { get; set; } public Level1ChildClass2 RootLevel1ChildClass21 { get; set; } } public class Level1ChildClass1 { public string Level1String1 { get; set; } public string Level1String2 { get; set; } public int Level1Int1 { get; set; } } public class Level1ChildClass2 { public string Level1String1 { get; set; } public string Level1String2 { get; set; } public int Level1Int1 { get; set; } public Level2ChildClass1 Level1Level2ChildClass11 { get; set; } public Level2ChildClass1 Level1Level2ChildClass12 { get; set; } public Level2ChildClass2 Level1Level2ChildClass22 { get; set; } } public class Level2ChildClass1 { public string Level2String1 { get; set; } public string Level2String2 { get; set; } public int Level2Int1 { get; set; } } public class Level2ChildClass2 { public string Level2String1 { get; set; } public string Level2String2 { get; set; } public int Level2Int1 { get; set; } } (例如,如果true具有带值的字符串属性)。

这是我到目前为止所拥有的:

RootLevel1ChildClass11

这在第一层上很有用(所以public static bool ObjectHasStringData<T>(this T obj) { var properties = typeof(T).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance); foreach (var property in properties) { Type propertyType = property.PropertyType; if (propertyType == typeof(string)) { try { if (!String.IsNullOrEmpty(property.GetValue(obj, null) as string)) return true; } catch (NullReferenceException) { } // we want to ignore NullReferenceExceptions } else if (!propertyType.IsValueType) { try { if (ObjectHasStringData(property.GetValue(obj, null))) return true; } catch (NullReferenceException) { } // we want to ignore NullReferenceExceptions } } return false; } 中的任何string都很好),但是一旦我开始在RootClass行上递归使用它,{{1}的返回值} {是if (ObjectHasStringData(property.GetValue(obj, null))),因此在递归调用方法时,property.GetValue()object

我可以获取当前对象的T,但如何将从object返回的Type转换为属性的实际类型?

1 个答案:

答案 0 :(得分:0)

我建议不要将它作为通用方法,让它接受任何对象,并使用GetType来获取类型(除非它是null)。这些泛型似乎并没有真正增加任何有价值的东西。

因此,删除type参数,使用obj.GetType(),如果对象为null,则不递归!

此外,(propertyType)obj)将不起作用,如果它将没有用。转换仅用于类型安全并确定(在编译时)如何与对象交互。对于System.Reflection,它没有任何区别。

public static bool ObjectHasStringData( this object obj )
{
    if( obj == null )
        return false;
    var properties = obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
    foreach (var property in properties)
     ...
}