2017-01-05 12 views
4

私はそうのように、キーと値の両方がタイプTypeのある辞書を持っている...私は何をしようとしているジェネリックでタイプのタイプを制限できますか?

private static Dictionary<Type, Type> myDict; 

FrameworkElementから継承する唯一の可能なタイプに2つ目のTypeを制限しています。私はFrameworkElementインスタンスをstoryingないよ

注、私は次の文が真作るFrameworkElementから派生タイプTypeの唯一のストアオブジェクトにしようとしている...

var isTypeStorable = typeof(FrameworkElement).IsAssignableFrom(FooType); 

は、だからそれを行うことができますか?

私は、上記(私が今やっているものです)辞書に追加する前にランタイムチェックを行うために使用できることを知っています。コンパイル時にこれを制限する機能があれば疑問です。

+0

のために私の知る限りでは何もありません。特殊な辞書を作成し、 'Add'メソッドと' AddRange'メソッドをオーバーライドし、入力が悪い場合はスローしますが、これは実行時エラーチェックのみを提供します。おそらく工場やDIを使って、あなたの究極の目標を達成するためのよりよい方法があるのだろうかと私はほとんど疑問に思いますか?辞書の使い方について少し詳しく説明できますか? –

+0

これは私が現在やっていることです。これは、言語の機能としての概念/機能について一般的に不思議に思っていました。 – MarqueIV

+0

一般的な制約は役に立ちませんか? 'T:FrameworkElement'のようなもの –

答えて

4

いいえこれはできません。 FrameworkElement.GetType()FooTypeは型システムに関係がなく、どちらもちょうどTypeです。ジェネリックを制限したい場合は、ランタイムチェックと例外を使用する必要があります。一般的な制約はここでは役に立ちません。

あなたはコンパイル時に格納したいものを知っている(またはいくつかの複雑な反射に満足している)あなたがTypeを取らないためにあなたのAPIを変更するが、代わりにジェネリックを使用することができた場合:

public void AddTypeForType(Type x, Type y) 

を置き換えることができます

public void AddTypeForType<T1, T2>() where T1 : FrameworkElement 
{ 
    myDict.Add(typeof(T1), typeof(T2)); 
} 

によってあなたは、このようにそれを呼び出すことができます。

AddTypeForType<FrameworkDerivedClass, MyCustomClass>(); 

しかし、それはあなたの質問に対する答えよりもAPIの変更のほうが多いです。

+0

2番目の例の意味が不明です。署名で使用していない2つのジェネリックタイプを指定しました。それがコンパイルされるかどうかは確かではありません。さらに、T1はTypeではなくFrameworkElement *インスタンスに制限されています。私はそれがTypeであるか、FrameworkElement型から派生したTypeオブジェクトに制限しようとしています。 – MarqueIV

+0

@MarqueIVそれを呼び出す例が追加されました。私が言ったように、それはあなたが望むものに近いAPIの変更ですが、コンパイル時に実際の型が分からなければ呼び出すのが非常に複雑です。 – nvoigt

+0

興味深いアプローチ!しかし、今はどのようにタイプの変数の実行時にそれを呼び出すのだろうか? ...または、その時点で手動でチェックする通常のAddメソッドを使用しますか? – MarqueIV

1

私はそのようなものはないと思います、しかし、あなたは辞書に追加する前に、項目をチェックすることによって、これを達成することができ、私はこのような何かを意味:

Xx,Yy私はmyDictに追加したい項目としますSO私ができることは、キーの存在を最初にチェックされていないし、その値のための条件(inherit from FrameworkElement.

if(!myDict.ContainsKey(Xx) && /* Yy is inherited from FrameworkElement */) 
{ 
    myDict.Add(Xx,Yy); 
} 
+0

ええ、それは私の 'isTypeStorable'フラグでやっていたことです。ランタイムではなく、コンパイル時にこれを得ることができるかどうかは不思議です。 – MarqueIV

+1

@MarqueIVもし 'myDict.Add(CallExternalFunction()、CallExternalFunction())'を持っていたら、コンパイル時に関数を実行せずに返された 'CallExternalFunction()'の型をコンパイラが知ることができましたか?ジェネリックスに切り替えてnvoigtの例を使用しない限り、コンパイル時には実行できません。 –

+0

これは間違いです。 'Add'メソッドは、それらの関数が正しい戻り値型を持たない場合にコンパイラーがそれをキャッチすることを意味しています。 – MarqueIV

関連する問題