1

次のクラスがあるとします。

public class Xyz {
}

public class Abc: Xyz {
}

public class Pqr: Xyz {
}

public class Wtf: Abc {
}

type1とtype2の共通ベースタイプを見つけるメソッドを使用して:

public static Type FindBaseClassWith(this Type type1, Type type2);

次に、次のコマンドでメソッドを呼び出します。

typeof(Wtf).FindBaseClassWith(variousType).FindBaseClassWith(typeof(Xyz));

variousTypeの変数はどこにありますかType、場合によってはnull

そして、FindBaseClassWith次のような連鎖呼び出しを意味します。

t1.FindBaseClassWith(t2).FindBaseClassWith(t3).FindBaseClassWith(t4);

それらの間の唯一の基本タイプを見つけるために。

メソッドは何をFindBaseClassWith返す必要がありますか?

最も受け入れられる答えは、それが解決策になるかどうかをマークすることです。

4

2 に答える 2

2

これは拡張メソッドであるため、チェーンのメンバーの1つがnullであっても正常に機能します。オブジェクトがパラメータとして渡されるメソッド呼び出しの構文糖衣であるため、null参照で拡張メソッドを呼び出すことができます。ただし、結果が。の場合、最後のNullReferenceExceptionようにプロパティにアクセスしようとすると、が表示されます。.Namenull

チェーン呼び出しを使用して一連のパラメーターを収集し、最後にそれらを「処理」するだけの場合は、LINQと同様のパターンが必要です。中間型は、チェーン内の値を単に収集するある種のラッパーである必要があります。次に、タイプを照合するプロセスを実際に開始する最後の呼び出し、つまりのようなものが必要.Resolve()です。これが呼ばれる実装例TypeChainです:

public class TypeChain
{
    private List<Type> types;

    public TypeChain(Type t)
    {
        types = new List<Type>();
        types.Add(t);
    }

    // searching for common base class (either concrete or abstract)
    public TypeChain FindBaseClassWith(Type typeRight)
    {
        this.types.Add(typeRight);
        return this;
    }

    public Type Resolve()
    {
        // do something to analyze all of the types
        if (types.All (t => t == null))
            return null;
        else
            types = types.Where (t => t != null).ToList();

        var temp = types.First();
        foreach (var type in types.Skip(1))
        {
            temp = temp.FindBaseClassWithHelper(type);
        }
        return temp;
    }
}

FindBaseClassWith静的実装にはいくつかの変更があります。

// searching for common base class (either concrete or abstract)
public static Type FindBaseClassWithHelper(this Type typeLeft, Type typeRight)
{
    if(typeLeft == null || typeRight == null) return null;

    return typeLeft
            .GetClassHierarchy()
            .Intersect(typeRight.GetClassHierarchy())
            .FirstOrDefault(type => !type.IsInterface);
}

// searching for common base class (either concrete or abstract)
public static TypeChain FindBaseClassWith(this Type typeLeft, Type typeRight)
{
    return new TypeChain(typeLeft).FindBaseClassWith(typeRight);
}

上記のチェーンロジックを使用すると、元のコードでは不可能なロジックシナリオが可能になります。すべてのエントリがであるかどうかを確認してからnull戻ることができるようになりました。そうでない場合は、結果を汚染しないように、処理する前にすべてのエントリを最初にパージすることができます。もちろん、これは任意のロジックに拡張できます。nullnullnull

于 2013-01-16T15:20:57.947 に答える
1

http://msdn.microsoft.com/en-us/library/system.type.basetype.aspxを参照してください

BaseType目的のタイプと繰り返し比較することにより、階層を横断する再帰関数を作成できます。

于 2013-01-16T14:30:47.583 に答える