16

オブジェクトが辞書かどうかをテストする方法はありますか?

メソッドで、リスト ボックスで選択した項目から値を取得しようとしています。状況によっては、リスト ボックスがディクショナリにバインドされることがありますが、これはコンパイル時にはわかりません。

私はこれに似たようなことをしたいと思います:

if (listBox.ItemsSource is Dictionary<??>)
{
    KeyValuePair<??> pair = (KeyValuePair<??>)listBox.SelectedItem;
    object value = pair.Value;
}

リフレクションを使用して実行時にこれを動的に行う方法はありますか? ジェネリック型でリフレクションを使用してキー/値パラメーターを決定できることはわかっていますが、それらの値を取得した後に残りを行う方法があるかどうかはわかりません。

4

8 に答える 8

13

IDictionary を実装しているかどうかを確認します。

System.Collections.IDictionary の定義を参照して、何が得られるかを確認してください。

if (listBox.ItemsSource is IDictionary)
{
    DictionaryEntry pair = (DictionaryEntry)listBox.SelectedItem;
    object value = pair.Value;
}

編集: KeyValuePair が DictionaryEntry にキャストできないことに気付いたときの代替

if (listBox.DataSource is IDictionary)
{
     listBox.ValueMember = "Value";
     object value = listBox.SelectedValue;
     listBox.ValueMember = ""; //If you need it to generally be empty.
}

このソリューションではリフレクションを使用しますが、この場合は面倒な作業を行う必要はなく、ListBox が代わりに行います。また、一般的に辞書をデータ ソースとして使用している場合は、常に ValueMember をリセットすることを回避できる場合があります。

于 2008-09-23T19:22:40.127 に答える
10

次のようになります。これは回答ボックスに書いたので、構文が正確ではないかもしれませんが、誰でも修正できるように Wiki で編集できるようにしました。

if (listBox.ItemsSource.IsGenericType && 
    typeof(IDictionary<,>).IsAssignableFrom(listBox.ItemsSource.GetGenericTypeDefinition()))
{
    var method = typeof(KeyValuePair<,>).GetProperty("Value").GetGetMethod();
    var item = method.Invoke(listBox.SelectedItem, null);
}
于 2008-09-23T19:27:55.417 に答える
1

IDictionaryを実装しているかどうかを確認できます。DictionaryEntryクラスを使用して列挙するだけです。

于 2008-09-23T19:23:03.590 に答える
0
if(typeof(IDictionary).IsAssignableFrom(listBox.ItemsSource.GetType()))
{

}
于 2010-01-05T23:59:24.273 に答える
0

もう少し一般的になり、代わりに を実装しているかどうかを尋ねることができますIDictionary。次に、KeyValue コレクションはプレーンに続きますObjects

于 2008-09-23T19:23:01.280 に答える
0

警告が出ていると思います。

オブジェクトがこれまたはあれであるかどうかをテストしているときは、型システム (の一部) を再実装しています。最初の 'is a' の後にすぐに 2 番目のコードが続くことが多く、すぐにコードが型チェックでいっぱいになります。これは、型システムによって非常にうまく処理される必要があります (少なくともオブジェクト指向設計では)。

もちろん、私は質問の文脈について何も知りません。私たち自身のコードベースで、50 の異なるオブジェクトから文字列への変換を処理する 2000 行のファイルを知っています... :(

于 2008-09-23T20:21:00.407 に答える
0

私は、タイプがディクショナリかどうかを判断する から来ています。そこにある答えのどれも私の問題を適切に解決していません。

ここでの最も近い答えはLukas Klusis によるものですが、IsDictionary(Type type)方法を提供するには不十分です。彼の答えからインスピレーションを得て、その方法を次に示します。

private static Type[] dictionaryInterfaces = 
{
  typeof(IDictionary<,>),
  typeof(System.Collections.IDictionary),
  typeof(IReadOnlyDictionary<,>),
};

public static bool IsDictionary(Type type) 
{
   return dictionaryInterfaces
    .Any(dictInterface =>
        dictInterface == type || // 1
        (type.IsGenericType && dictInterface == type.GetGenericTypeDefinition()) || // 2
        type.GetInterfaces().Any(typeInterface => // 3
                                 typeInterface == dictInterface ||
                                 (typeInterface.IsGenericType && dictInterface == typeInterface.GetGenericTypeDefinition())));
}

// 1住所public System.Collections.IDictionary MyProperty {get; set;}

// 2住所public IDictionary<SomeObj, SomeObj> MyProperty {get; set;}

// 3(つまり、2 番目の) は、タイプのいずれかを実装する.Anyシナリオに対応します。typedictionaryInterfaces

他の回答の問題は、#3に対処していると仮定して、#1と#2に対処していないことです。プロパティのタイプを取得してチェックすることはおそらく一般的なシナリオではないため、これは理解できます。しかし、あなたが私のようで、そのシナリオあなたのユースケースの一部である場合は、どうぞ!

于 2021-06-22T04:24:23.067 に答える