2009-08-27 3 views
18

C#でparam引数をキャストすることは可能ですか?C#のパラメータをキャストしていますか?

Dictionary<string,object> dict; // but I know all values are strings 
string key, value; 

は、大雑把に言えば(と私は静的型付けを持っていなかった場合は)私が何をしたい:私は持っている

dict.TryGetValue(key, out value); 

が、それは「アウト」から変換することはできませんので、これは明らかにコンパイルされません文字列 'から'オブジェクトを外に出す '。

私が使用している回避策は次のとおりです。

object valueAsObject; 
dict.TryGetValue(key, out valueAsObject); 
value = (string) valueAsObject; 

が、それはむしろ厄介なようです。

メソッドコールでoutパラメーターをキャストできるようにするための言語機能はありますか?それで私はこのswitcherooを実行しますか?私は助けになる構文を理解することはできませんし、私はグーグルで何かを見つけることができません。

答えて

2

すべての値が文字列であることがわかっている場合は、代わりにDictionary<string, string>を使用してください。 outパラメータ型は、第2ジェネリック型パラメータの型によって設定されます。あなたのオブジェクトは現在オブジェクトなので、辞書から取得するときにオブジェクトを返します。文字列に変更すると、文字列が返されます。

+4

Dictionary は、私が使用しているインタフェースによって提供されています。私はすべての値が私の使用のための文字列であることを知っています。なぜなら、それは私がここでそれを埋めているからです。 – Ken

0

いいえ、できません。メソッド内のコードは、渡された変数を直接変更しています。変数の内容のコピーは渡されません。

2

いいえ、回避策はありません。 outパラメーターには、正確に一致する変数が必要です。

辞書には文字列以外のものを含めることができるため、文字列参照を使用するのは安全ではありません。しかし、文字列の辞書を持っていて、TryGetValue呼び出しでオブジェクト変数を使用しようとすると、それは安全であっても機能しません。変数型は正確に一致しなければなりません。

18

それは素晴らしいアイデアであるかどうかは知りませんが、一般的な拡張メソッドを追加することができます。

static bool TryGetTypedValue<TKey, TValue, TActual>(
     this IDictionary<TKey, TValue> data, 
     TKey key, 
     out TActual value) where TActual : TValue 
    { 
     TValue tmp; 
     if (data.TryGetValue(key, out tmp)) 
     { 
      value = (TActual)tmp; 
      return true; 
     } 
     value = default(TActual); 
     return false; 
    } 
    static void Main() 
    { 
     Dictionary<string,object> dict 
      = new Dictionary<string,object>(); 
     dict.Add("abc","def"); 
     string key = "abc", value; 
     dict.TryGetTypedValue(key, out value); 
    } 
+0

これは構文的な砂糖の興味深いビットです。 –

+0

+1これは決して辞書ではできませんでしたが、非常によく似たヘルパー拡張メソッドがあります。 –

+1

私がおそらく変更を検討する唯一のものは、値が見つかったが間違ったタイプのケースの処理です。投げるのではなく、ただ偽に戻したいと思うかもしれません。それではまた、私はそうではないかもしれません。私はこれを考える必要があるだろうが、それは言及する価値がある。 –

2

私はマルクの拡張メソッドを使用しますが、それにビットを追加しました。

私の問題は、私の辞書にはint64が含まれているのに対し、辞書にはint32が含まれていることがあります。それ以外の場合、辞書には文字列(たとえば "42")が含まれていますintとして。

私は、変換メソッドにデリゲートに渡す機能を追加しましたので、マルクの方法で変換を処理する方法はありません:

あなたは、このように呼び出すことができます
internal static bool TryGetTypedValue<TKey, TValue, TActual>(
     this IDictionary<TKey, TValue> data, 
     TKey key, 
     out TActual value, Func<TValue, TActual> converter = null) where TActual : TValue 
    { 
     TValue tmp; 
     if (data.TryGetValue(key, out tmp)) 
     { 
      if (converter != null) 
      { 
       value = converter(tmp); 
       return true; 
      } 
      if (tmp is TActual) 
      { 
       value = (TActual) tmp; 
       return true; 
      } 
      value = default(TActual); 
      return false; 
     } 
     value = default(TActual); 
     return false; 
    } 

int limit; 
myParameters.TryGetTypedValue("limitValue", out limit, Convert.ToInt32) 
関連する問題