如何递归调用分析属性的泛型方法 [英] how to recursively call a generic method analyzing properties

查看:95
本文介绍了如何递归调用分析属性的泛型方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个方法来分析我创建的类的一个实例,检查该类的每个属性 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 those string properties are null 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, if RootLevel1ChildClass11 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 the RootClass), but once I start using it recursively on the if (ObjectHasStringData(property.GetValue(obj, null))) line, the return value of property.GetValue() is object, so when calling the method recursively, T is object.

I can get the Type of the current object, but how do I convert the object returned from property.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆