以下の状況を考慮してください。私はDictionary<string,string> dictionary
とstring key
を持っています。私はコンパイル時にこれら2つの型を知らないが、実行時にそれらを知っている。だから、コンパイル時には、それらは単なるオブジェクトです。私は、辞書dictionary.ContainsKey(key)を呼び出したいと思う。しかし、keyは "オブジェクトへのキャスト"という文字列であるため、RuntimeBinderExceptionが発生します。私はこの問題を解決する方法を理解したいと思います。ここで 実行時にのみ既知の型にオブジェクトをキャストする方法
[TestMethod]
public void ThisTestFails()
{
dynamic dictionary = getDict();
var key = getKey();
bool result = dictionary.ContainsKey(key);
Assert.IsTrue(result);
}
[TestMethod]
public void ThisTestWorks()
{
dynamic dictionary = getDict();
var key = (string)getKey();
bool result = dictionary.ContainsKey(key);
Assert.IsTrue(result);
}
private object getDict() => new Dictionary<string, string>() { { "abc", "def" } };
private object getKey() => "abc";
ThisTestFails
はThisTestWorks
通過する間、RunTimeBinderException
で失敗します。だから、両方のテストの変数key
に文字列が含まれていますが、ThisTestFails
の見かけの型はオブジェクトであり、dictionary.ContainsKey
では使用できません。
これを解決する必要があるのは、実行時にkey
変数を文字列にキャストする方法です。 ThisTestWorks
の(string)key
の解は私にとっては役に立たないでしょう。一般的なケースでは私はコンパイル時に辞書のキーの型を知らないからです。問題を解決するために何ができるのですか?
実際にキーの種類がコンパイル時にわからないときに、辞書が 'string'型キーを使用しているのはなぜですか?単に 'object'型をキーとして使うことを考えましたか?あなたの辞書のキーが "任意のタイプのオブジェクト"であることができるとき、IMHOは、(テキストを使用する代わりに)キーを表すために 'object'タイプを使用する方が理にかなっています。 – bassfader
文字列のキーと値は単なる例に過ぎません。実際には、ディクショナリはリフレクションによって検出され、非常に分かりやすいジェネリック型のパラメータを持っていますが、実行時にクライアントからは分かりません。ディクショナリはかなり異なるクラスのプロパティからのものである可能性があるからです。だから、キー型としてオブジェクトを持たないのが良い理由です。 –
これはXYの問題かもしれないので、解決しようとしている実際の問題を共有することでメリットが得られるかもしれません。多くの場合、C#では 'dynamic'を避けることができます。 – Groo