2012-04-19 9 views
0

文字列を受け取るWebサービスがあります。ディクショナリに格納されている引数が有効かどうかを確認します。

この文字列には複数のキー=>値が含まれています。これらの値は文字 '+'で連結されています。

各値( "必須"、 "空でない")を検証し、それぞれを同じ名前の変数に割り当てる必要があります。ここで

は、私は、文字列から辞書を構築する方法である:スペルミスのため

string firstname; 
string lastname; 
string amount; 

string request = "firstname=foo+lastname=bar+amout=100.58"; 

Dictionary<string, string> arguments = new Dictionary<string, string>(); 

request.Split('+').ToList<string>().ForEach(p => 
{ 
    string[] tmp = p.Split('='); 

    if (tmp.Length == 2) 
     arguments.Add(tmp[0], tmp[1]); 
}); 

// Validate and assign : How I do with one value : (I must find a better way) 
bool isValid = true; 

// check "firstname" 
if(arguments.ContainsKey("firstname") && string.IsNullOrWhiteSpace(arguments["firstname"]) == false) 
{ 
    firstname = arguments["firstname"]; 
} 
else 
{ 
    isValid = false; 
    Logger.Write("Invalid argument : firstname"); 
} 

// Do this for about 20 arguments, it becomes huge... 

if(isValid) 
{ 
    Console.WriteLine(firstname); // Displays foo 
    Console.WriteLine(lastname); // Displays bar 
    Console.WriteLine(amout); // Displays 100.58 
} 

おかげで、と申し訳ありませんが、私はフランス人です。また

request.Split('+').ToList<string>().ForEach(p => 
{ 
    string[] tmp = p.Split('='); 

    if (tmp.Length == 2 && !string.IsNullOrWhiteSpace(tmp[1])) 
    { 
     // edit - if your string can have duplicates, use 
     // Dictionary<U,K>.ContainsKey(U) to check before adding 
     var key = tmp[0]; 
     var value = tmp[1]; 

     if(!arguments.ContainsKey(key)) 
     { 
      arguments.Add(key, value); 
     } 
     else 
     { 
      //overwrite with new value 
      //could also maybe throw on duplicate or some other behavior. 
      arguents[key]=value; 
     } 
    } 
    else 
     throw InvalidOperationException("Bad dictionary string value"); 
}); 

は、私がToList->のForEachを使用する場合を疑問視します:

+2

HMのお役に立てば幸いです。..実際の問題は何ですか? – Tigran

+0

何を有効にしますか? –

+0

たとえば、firstnameが辞書に存在するかどうか、辞書が空でない場合、変数 "firstname"にdictionaryの値を入力する方法を調べる方法はわかりません。事実、約20の議論があり、それぞれを検証するには非常に巨大になる。 –

答えて

0

私はあなたがこのような何かをしたいが、あなたはacutally質問をしていなかったので、私はちょうど推測している思いこれはコードレビューで私の前にありました。あなたは、LINQのでは副作用を避けたい、私のような伝統的なforeachのとそれを記述します。

var itemValues = request.Split('+'); 
foreach(var item in itemValues) 
{ 
    string[] tmp = item.Split('='); 

    if (tmp.Length == 2 && !string.IsNullOrWhiteSpace(tmp[1])) 
     arguments.Add(tmp[0], tmp[1]); 
    else 
     throw InvalidOperationException("Bad dictionary string value"); 
}); 



// Validate and assign 
//read values from the dictionary 
//use ContainsKey to check for exist first if needed 

Console.WriteLine(arguments["firstname"]); // Displays foo 
Console.WriteLine(arguments["lastname"]); // Displays foo 
Console.WriteLine(arguments["amout"]); // Displays 100.58 

編集2 - あなたはこの方法でロジックをカプセル化する必要があります。

private string TryGetValue(IDictionary<string,string> dict,string key) 
{ 
    string value = null; 
    if(dict.ContainsKey(key) && !string.IsNullOrWhiteSpace(dict[key])) 
    { 
     value = dict[key]; 
    } 
    else 
    { 
     Logger.Write("Invalid argument : " + key); 
    } 
    return value; 
} 

今、あなたが言うことができます。

public static class Extensions 
{ 
    public static string TryGetValue(this IDictionary<string,string> dict, string key) 
    { 
     string value = null; 
     if(dict.ContainsKey(key) && !string.IsNullOrWhiteSpace(dict[key])) 
     { 
      value = dict[key]; 
     } 
     else 
     { 
      Logger.Write("Invalid argument : " + key); 
     } 
     return value; 
    } 

} 
012:

string firstName = TryGetValue(arguments,"firstname"); 
string lastName= TryGetValue(arguments,"lastName"); 
string amount = TryGetValue(arguments,"amount"); 

bool isValid = firstName!=null && lastName != null && amount != null; 

if(isValid) 
{ 
    Console.WriteLine(firstName); // Displays foo 
    Console.WriteLine(lastName); // Displays bar 
    Console.WriteLine(amout); // Displays 100.58 
} 

TryGetValueは、優れた拡張メソッドになるだろう

今すぐ呼び出し元のコードは次のようになります。

string firstName = arguments.TryGetValue("firstname"); 
string lastName= arguments.TryGetValue("lastname"); 
string amount = arguments.TryGetValue("amount"); 

最終編集 - 拡張子法に ノート - はい、彼らはきちんとしているが、それは誤ってそれらを乱用悪い状況で取得することも簡単です。 msdnやブログについては、ガイドラインに従ってください。 object,stringなどの一般的な種類の拡張は避けてください。

namespace Extensions.IDictionary { ... } 
namespace Extensions.string { ... } 
namespace Extensions.SomeType { ... } 
namespace Extensions.IList { ... } 

と消費のコードを:私のプロジェクトで

は、私はいつものような非常にそれについて解明することにそれらを使用したいクラスを強制的に、彼らはとの対話種類に応じて個別の名前空間の拡張メソッドをレイアウト何より、中にあなたの興味にちょうど拡張子を引っ張って

using Extensions.IDictionary; 

:一致するusing句を持っていないだろう。

+0

ありがとう、私はC#で新しいです、私は拡張メソッドについて知りませんでした。クールな機能! –

+0

@AsKaiser問題ありません!将来は混乱を避けるためにできるだけ多くの情報をあなたの質問に書いてみてください。誰も推測するのが好きではありません!あなたのための拡張メソッドについての短いメモを追加しました。 – asawyer

0

これはあなたの質問が明確でないため、これは単なる推測です。

// Validate and assign 

foreach(KeyValuePair<string,string> pair in arguments) 
{ 
    if(!String.IsNullOrEmpty(pair.Value)) 
    { 
     Console.WriteLine(pair.Value); 
    } 
} 
0

firstnames、lastnames、およびmoreが1つ以上ある場合は、List of Value of Dictionaryを使用できます。 この方法では、firstname、lastnameなどの値を単純に追加できます。あなたは辞書に値を追加することの間でそれを行うことができ、検証するために

string request = "firstname=foo+lastname=bar+amout=100.58+firstname=+lastname=bar2+amout=100.59+firstname=foo3+lastname3=bar3+amout=100.60"; 

     Dictionary<string, List<string>> arguments = new Dictionary<string, List<string>>(); 
     request.Split('+').ToList<string>().ForEach(f => 
      { 
       string[] data = f.Split('='); 
       if (data.Length == 2) 
       { 
        if (!arguments.ContainsKey(data[0])) 
        { 
         if (data[1] != "") 
          arguments.Add(data[0], new List<string> { data[1] }); 
         else 
          arguments.Add(data[0], new List<string> { "no firstname" }); 
        } 
        else 
        { 
         if (data[1] != "") 
          arguments[data[0]].Add(data[1]); 
         else 
          arguments[data[0]].Add("no firstname"); 
        } 
       } 
      }); 

が、それは、 さようなら

関連する問題