0

関数本体内で汎用メカニズムを使用することは可能ですか?

たとえば

if (!(someClass is IClass<T, G> where T : someInterface, G : anotherInterface))
{
    return;
 }

または、次のようにキャストします。

var v = (IClass <T, G> where T : someInterface, G: anotherInterface)something;
4

4 に答える 4

1

これを行うことができますが、インターフェイスが共変であることを確認する必要があります。

interface IClass<out T, out S>
{
    // Methods that can return a T or S but not accept one as input
}

型パラメーターを としてマークすることで、基本的に「このインターフェイスからは aまたはouta のみを取得する」と言っています。たとえば、リストから aしか取得できないのは、 a をリストに入れることも 1 つを取得することもできるからです。TS IEnumerable<out T>TList<T>T

インターフェースをそのように定義すると、 anIClass<string, string> anです。あなたは、あなたが a だけを与えることIClass<object, object>を知っていますが、 aは an であるので、それは問題ありません。IClass<string, string>stringstringobjectIClass<object, object>object

(インターフェイスで aまたは an何かに入れることができる場合、これを行うことはできません。この場合、 yourを anに割り当てた場合、an をそれに入れようとすると失敗します。実際には a のみを受け入れます。)TS IClass<string, string>IClass<object, object>intstring

これでできることは

if (!(something is IClass<object, object>))
{
    return;
}

また

var v = (IClass<object, object>)something;

something実際にを実装するオブジェクトである場合、両方とも機能しますIClass<string, string>

于 2012-12-12T08:36:18.377 に答える
1

最初の例では、はい - タイプを指定するだけです:

if (!(someClass is IClass<ISomeInterface, IAnotherInterface>))
{
    return;
 }

もう1つはほとんど同じです。

var v = (IClass <ISomeInterface, IAnotherInterface>)something;

おそらく使用する方が良いですがas

var v = something as IClass <ISomeInterface, IAnotherInterface>;
if(v != null)
{
    // Do something.
}

上記の 2 行目は重要asです。直接キャストの代わりに使用すると、失敗したInvalidCastException場合は取得されませんが、v使用したキャストが失敗した場合は null になりasます。この手法を使用すると、キャストの試行が無効な場合に、失敗をもう少し制御できます。(変換が無効になる理由を考えてみてください。それが、世界がどのように見えるかをより長く知っている状況を表している場合InvalidCastExceptionは、おそらく正しいアプローチです。オブジェクトがインターフェイスのインスタンスではないasことが合理的である場合は、友達。)

于 2012-12-12T08:09:50.370 に答える
0

あなたはこれを試すことができます:

if (!(someClass is IClass<someInterface, anotherInterface>)
{
    return;
}

またはリフレクション経由:

var t = someClass.GetType()
Type[] typeParameters = t.GetGenericArguments();
if (!typeParameters[0].IsSubclassOf(typeof(someInterface)) || 
    !typeParameters[1].IsSubclassOf(typeof(anotherInterface)))
{
    return;
}
于 2012-12-12T08:12:08.490 に答える
0

whereジェネリック メソッド自体に制約が適用されます。目的のタイプを問題なく使用できます。

余談ですが、 falseをチェックしないでください。長い目で見ると混乱を招きます。

if (someClass is IClass<someInterface, anotherInterface>)
{
    // your code
}
// else { return; } // no longer needed!

コードを展開してジェネリック メソッドに含めると、次のようになります。

void myMethod<T, U>()
    where T : someInterface
    where U : anotherInterface
{
    if (someClass is IClass<T, U>)
    {
        // your code
    }
    // else { return; } // no longer needed!
}
于 2012-12-12T08:14:55.720 に答える