2

を受け取り、応答のコンテンツを変更するTメソッドを持つクラスがあります。HttpResponseMessage

public class MyClass<T> {

    HttpResponseMessage Modify(HttpResponseMessage response) {
        T content;
        if(response.TryGetContentValue(out content)) {
            DoSomethingWithContent(content);
        }
        return response;
    }

    public void DoSomethingWithContent(T content) {}

    public void DoSomethingWithContent(IEnumerable<T> content) {}
}

このように使用...

Tこれは、応答コンテンツの値がタイプで ある限り機能しますが、場合によってはタイプであり、そうでないIEnumerable<T>場合TryGetContentValue()は false を返しますTIEnumerable<T>。そのため、オーバーロードを作成しましたが、正しいオーバーロードが呼び出されるように、適切な型DoSomethingWithContentに動的にキャストまたは宣言する効率的な方法を見つけるのに苦労しています。content

答え

私はrecursive答えを出しましたが、参考のために完全な方法を投稿したかったのです:

public class MyClass<T> {

    HttpResponseMessage Modify(HttpResponseMessage response) {
        object content;
        if(response.TryGetContentValue(out content)) {
            if(content is IEnumerable<T>)
                DoSomethingWithContent((IEnumerable<T>)content);
            else
                DoSomethingWithContent((T)content);
        }
        return response;
    }

    public void DoSomethingWithContent(T content) {}

    public void DoSomethingWithContent(IEnumerable<T> content) {}
}
4

5 に答える 5

7

isを使用して、使用するケースを決定できます。

if (content is IEnumerable<T>)
    DoSomethingWithContent((IEnumerable<T>)content);
else
    DoSomethingWithContent(content);

生意気な場合は、動的にキャストしてランタイム バインダーを使用することもできますが、それはお勧めしません。

DoSomethingWithContent((dynamic)content);
于 2013-05-29T20:45:42.013 に答える
2

共変なので、もしあなたがIEnumerable<out T>...

var enumerable = content as IEnumerable<T>;
if (enumerable == null)
    DoSomethingWithContent(content);
else
    DoSomethingWithContent(enumerable);

DoSomethingWithContent(IEnumerable<T> content)...の実際の実行時の型が であっても、contentそれでもIEnumerable<C>呼び出されCますT


IEnumerable<T>これは、そもそも「フィット」しようとしている理由に対処していませんTか?

于 2013-05-29T20:57:31.610 に答える
1

ええ、あなたのデザインには循環性の問題があります。たとえば、ifMyClass<T>が初期化されているため、オーバーロードされた定義は実際には呼び出されません。実際に行う必要があるのは、メソッドを 1 つだけ使用することですが implementsかどうかをテストする句を用意することです。これは次のように行うことができます。MyClass<List<string>>T = List<string>TIEnumerable<T>

if (content is IEnumerable<T>)

IEnumberable が使用する型を指定する必要さえあるかもしれないので、それが機能するかどうかは完全にはわかりません。その場合は、ジェネリック バージョンを実装するすべてのコレクションも非ジェネリック バージョンを実装するため、非ジェネリック IEnumberable を実装するかどうかを確認します。

于 2013-05-29T20:48:53.927 に答える