12

単一のジェネリックメソッドを持つインターフェースがあるとします。

public interface IExtender
{
    T GetValue<T>(string tag);
}

そして、「タグ」パラメータに応じて2つの異なるタイプ(BとC)のインスタンスを返すその単純な実装A:

public class A : IExtender
{
    public T GetValue<T>(string tag)
    {
        if (typeof(T) == typeof(B) && tag == null)
            return (T)(object) new B();
        if (typeof(T) == typeof(C) && tag == "foo")
            return (T)(object) new C();
        return default(T);
    }
}

ダブルキャストを回避することは可能(T)(object)ですか?または、コンパイラに「このキャストは実行時に失敗しないと確信しています。最初にオブジェクトにキャストせずに実行させてください」と伝える方法はありますか。

4

6 に答える 6

9

または、コンパイラに「このキャストは実行時に失敗しないと確信しています。最初にオブジェクトにキャストせずに実行させてください」と伝える方法はありますか。

いいえ、言語はこれを防ぐために意図的に設計されています。Eric Lippertは、最近これについてブログに書いています。煩わしいことには同意しますが、ある種の意味はあります。

正直なところ、このような「一般的な」方法は、通常、少しデザインの匂いがします。メソッドにさまざまなタイプの特殊なケースが必要な場合は、少なくとも代わりに個別のメソッドを使用することを検討する必要があります。(GetBGetC

于 2012-07-19T07:21:50.770 に答える
6
public T MyMethod<T>(string tag) where T : class
    {
        return new A() as T;
    }
于 2012-07-19T07:28:29.650 に答える
3

このサンプルを確認してください。

    public T GetValue<T>(string tag) where T : class, new()
    {
        if (typeof(T) == typeof(B) && tag == null)
            return new T();
        if (typeof(T) == typeof(C) && tag == "foo")
            return new T();
        return default(T);
    }

キャストは必要ありません。「T」のインスタンスを作成できます。Tはクラスであり、パラメーターなしのコンストラクターがあるため、別の基本型を作成する必要がなく、適切な型のみを確認できるというジェネリック制約を追加するだけです。この一般的な方法を実行します。

于 2012-07-19T07:26:47.483 に答える
1

動的を使用して実際の結果を格納できますが、一般的な引数の型が正しい型であることを確認する必要があります。

TResult GetResult<TResult>() 
{
    dynamic r = 10;
    return r;
}
于 2018-10-17T20:51:47.443 に答える
0

BとCに同じインターフェースを実装させる場合は、に型制約を使用できますT。おそらくあなたが望むものとは正確には一致しませんが、他の人からも示唆されているように、あなたが望むものは実際には不可能です。

public interface IclassBndC {}

public class B : IclassBandC {}

public class C : IclassBandC {}

public class A : IExtender
{
    public T GetValue<T>(string tag) where T : IclassBandC 
    {
        if (tag == null)
            return new B();
        if (tag == "foo")
            return new C();
        return default(T);
    }
}
于 2012-07-19T07:24:15.273 に答える
0

いいえ、それは不可能です。これを行う唯一の方法は、コンパイラにの追加の仮定について知らせることTです。一般的なパラメーター制約のリストから明らかなように、特定のキャストの可用性を要求する制約はC#で定義されていません。

于 2012-07-19T07:22:49.733 に答える