2

我需要递归地遍历我的类中的所有属性,如果属性恰好是一个字符串,我需要做一些自定义逻辑。请告知我需要在递归行中添加的内容。

void ProcessAllStrings<T>(ref T objToRip)
{
    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
    Type typeParameterType = typeof (T);

    foreach (PropertyInfo p in typeParameterType.GetProperties(flags))
    {
        Type currentNodeType = p.PropertyType;
        if (currentNodeType == typeof (String))
        {
            //here I do my custom string handling. Code deleted
        }
            //if non primitive and non string then recurse. (nested/inner class instances)
            // see http://stackoverflow.com/questions/4444908/detecting-native-objects-with-reflection
        else if (currentNodeType != typeof (object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object)
        {
            //I need to get the reference to this property which happens to be a nested class
            //but propertyInfo only provides GetValue(). No GetReference available..
            ProcessAllStrings(ref "dont know what to put here");
        }
    }
}
4

4 回答 4

2

如果它是引用类型,那么我相信该值引用。要递归,只需将属性值传回函数:

            else if (currentNodeType != typeof (object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object)
            {
                object propVal = p.GetValue(objToRip,null);

                if(propVal != null) ProcessAllStrings(ref propVal);
            }

我还建议为索引属性添加一个处理程序。

于 2012-06-25T21:59:59.473 回答
2

基本上是我在评论中所说的以及 Mangist 所说的。这是一个还检查嵌套类型引用上的无限循环的实现:

private void ProcessAllStrings(Type objectType, HashSet<Type> typesChecked)
{
    if (typesChecked == null)
        typesChecked = new HashSet<Type>();

    if (typesChecked.Contains(objectType))
        return;

    typesChecked.Add(objectType);

    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

    foreach (PropertyInfo p in objectType.GetProperties(flags))
    {
        Type currentNodeType = p.PropertyType;
        if (currentNodeType == typeof (String))
        {
            //here I do my custom string handling. Code deleted
            Console.WriteLine("Found String Property: " + currentNodeType.FullName + " -> " + p.Name);
        }
            //if non primitive and non string then recurse. (nested/inner class instances)
            // see http://stackoverflow.com/questions/4444908/detecting-native-objects-with-reflection
        else if (currentNodeType != typeof (object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object)
        {
            //I need to get the reference to this property which happens to be a nested class
            //but propertyInfo only provides GetValue(). No GetReference available..
            ProcessAllStrings(currentNodeType, typesChecked);
        }
    }
}

所以,说像这样的类,注意Foo有 aBar也指向Foo,所以我们可以测试它不会无限循环:

public class Foo
{
    public string Prop1 { get; set; }
    public Bar Prop2 { get; set; }
}

public class Bar
{
    public string BarProp { get; set; }
    public Foo NestedFoo { get; set; }
}

你可以这样称呼它:

ProcessAllStrings(typeof(Foo), null);
于 2012-06-25T22:00:23.643 回答
0

您的方法需要一个对象引用,因此您需要创建所有这些嵌套类的实例才能使递归工作。您真正想要的是传递类型信息。

Type typeParameterType用作参数,而不是 objToRip 。

然后你可以调用ProcessAllStrings(currentNodeType );做递归

于 2012-06-25T21:52:25.303 回答
0

您可以使用动态类型而不是泛型类型:

public static void ProcessAllStrings(dynamic objToRip)
{
    if (objToRip == null) return;
    BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
    Type typeParameterType = objToRip.GetType();

    foreach (PropertyInfo p in typeParameterType.GetProperties(flags))
    {
        Type currentNodeType = p.PropertyType;
        if (currentNodeType == typeof(String))
        {
            //here I do my custom string handling. Code deleted
        }
        else if (currentNodeType != typeof(object) && Type.GetTypeCode(currentNodeType) == TypeCode.Object)
        {
            ProcessAllStrings(p.GetValue(objToRip, null));
        }
    }
}
于 2012-06-25T22:12:59.160 回答