如何递归调用分析属性的泛型方法 [英] how to recursively call a generic method analyzing properties
问题描述
我创建了一个方法来分析我创建的类的一个实例,检查该类的每个属性 string
类型,然后检查if那些字符串
属性是 null
或为空。
代码:
public class RootClass
有一个带有值的字符串属性。)
{
public string RootString1 {get;组; }
public string RootString2 {get;组; }
public int RootInt1 {get;组; }
public Level1ChildClass1 RootLevel1ChildClass11 {get;组; }
public Level1ChildClass1 RootLevel1ChildClass12 {get;组; }
public Level1ChildClass2 RootLevel1ChildClass21 {get;组; }
}
public class Level1ChildClass1
{
public string Level1String1 {get;组; }
public string Level1String2 {get;组; }
public int Level1Int1 {get;组; }
}
public class Level1ChildClass2
{
public string Level1String1 {get;组; }
public string Level1String2 {get;组; }
public int Level1Int1 {get;组; }
public Level2ChildClass1 Level1Level2ChildClass11 {get;组; }
public Level2ChildClass1 Level1Level2ChildClass12 {get;组; }
public Level2ChildClass2 Level1Level2ChildClass22 {get;组; }
}
public class Level2ChildClass1
{
public string Level2String1 {get;组; }
public string Level2String2 {get;组; }
public int Level2Int1 {get;组; }
}
public class Level2ChildClass2
{
public string Level2String1 {get;组; }
public string Level2String2 {get;组; }
public int Level2Int1 {get;组; }不是所有的类的属性都是字符串,其中一些是实例的其他类,它们有自己的属性,这也需要以同样的方式进行分析。基本上,如果任何属性是RootClass上的值或类的子级别上的任何位置的字符串(例如,如果<$ c),则该方法将返回true
$ c> RootLevel1ChildClass11
这是我到目前为止:
public static bool ObjectHasStringData< T>(this T obj)
为属性的实际类型?
{
var properties = typeof(T).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
foreach(属性中的var属性)
{
类型propertyType = property.PropertyType;
if(!String.IsNullOrEmpty(property.GetValue(obj,null)as string)如果(propertyType == typeof(string))
{
try
{
if ))
返回true;
}
catch(NullReferenceException){} //我们要忽略NullReferenceExceptions
}
else if(!propertyType.IsValueType)
{
try
{
if(ObjectHasStringData(property.GetValue(obj,null)))
return true;
}
catch(NullReferenceException){} //我们要忽略NullReferenceExceptions
}
}
return false;
$ b这对第一层很有用(所以任何
),但是一旦我开始在
RootClass
中的字符串上递归使用if(ObjectHasStringData(property.GetValue(obj ,null)))
行,property.GetValue()
的返回值是object
,所以当递归调用方法时,T
是object
。
我可以获取当前对象的
Type
,但是如何转换从<返回的对象
code> property.GetValue()
解决方案我建议不要使用这个泛型方法,只要让它接受任何对象,并使用
GetType
来获取类型(除非它为空)。在这里泛型似乎没有增加任何有价值的东西。
因此,删除类型参数,使用
obj.GetType() code>,如果对象为空,则不递归!
另外,
(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属性)
...
}
I'm creating a method that will analyze an instance of a class that I have created, checking each of the properties on that class for
string
types and then checking if thosestring
properties arenull
or empty.Code:
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; } }
Not all the properties on the class are strings, some of them are instances of other classes, which have their own properties, which also need to be analyzed the same way. Basically, the method will return
true
if any of the properties are strings with a value on the RootClass or anywhere on sub-levels of the class (for example, ifRootLevel1ChildClass11
has a string property with a value).Here's what I have so far:
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; }
this works great on the first layer (so any
string
within theRootClass
), but once I start using it recursively on theif (ObjectHasStringData(property.GetValue(obj, null)))
line, the return value ofproperty.GetValue()
isobject
, so when calling the method recursively,T
isobject
.I can get the
Type
of the current object, but how do I convert theobject
returned fromproperty.GetValue()
to the actual type of the property?解决方案I'd suggest not making that a generic method, just have it accept any object, and use
GetType
to get the type (unless it's null). The generics doesn't really seem to add anything of value here.So, remove the type parameter, use
obj.GetType()
, and don't recurse if the object is null!Also,
(propertyType)obj)
won't work, and if it would it would have no use. Casting is only for type safety and determining (at compile time) how to interact with an object. To System.Reflection it doesn't make any difference.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) ... }
这篇关于如何递归调用分析属性的泛型方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!