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てください。これにより、無限にループしないことをテストできます。BarFoo

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 typeParameterTypeobjToRipの代わりに引数として使用します。

次に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 に答える