2017-09-01 5 views
1

私はHttpContext contextを持っており、情報を収集するためにそのRequestプロパティのいくつかを反復します。現在、私はそれをこのように実行します。1つの汎用メソッドを使用して、さまざまなタイプの辞書を反復処理するにはどうすればよいですか?

if (context.Request.Headers?.Keys != null) 
{ 
    var items = new StringBuilder(); 
    foreach (var key in context.Request.Headers.Keys) 
    { 
     items.AppendLine(key + " = " + context.Request.Headers[key]); 
    } 
    result.Headers = items.ToString(); 
} 
if (context.Request.Form?.Keys != null) 
{ 
    var items = new StringBuilder(); 
    foreach (var key in context.Request.Form.Keys) 
    { 
     items.AppendLine(key + " = " + context.Request.Form[key]); 
    } 
    result.Form = items.ToString(); 
} 
if (context.Request.Query?.Keys != null) 
{ 
    var items = new StringBuilder(); 
    foreach (var key in context.Request.Query.Keys) 
    { 
     items.AppendLine(key + " = " + context.Request.Query[key]); 
    } 
    result.Query = items.ToString(); 
} 

が、私は一般的な方法(あなたが他の方法を提案することができれば、私はあまりにも、彼らと罰金になります)に、この反復コードを変換したいです。

private static string ParseKeys<T>(IDictionary<object, object> dict) 
{ 
    var sb = new StringBuilder(); 
    foreach (var key in dict.Keys) 
    { 
     sb.AppendLine(key + " = " + dict[key]); 
    } 
    return sb.ToString(); 
} 

とこのようにそれを呼び出す:私はさまざまな組み合わせを試してみましたが、私はまだに管理することができませんでしたcannot convert from 'Microsoft.AspNetCore.Http.IHeaderDictionary' to 'System.Collections.Generic.IDictionary<object, object>'

:私は、このようなエラーが出

result.Headers = ParseKeys<IHeaderDictionary>(context.Request.Headers); 
result.Form = ParseKeys<IFormCollection>(context.Request.Form); 
result.Query = ParseKeys<IQueryCollection>(context.Request.Query); 

しかし、私は一般的な方法を書いてみましたエラーを避ける。私はここで不可能にしようとしているのですか、または私が欲しいことをするのは簡単ですか?ので、ここであなたが一般的な方法を必要としないIEnumerable<KeyValuePair<string, StringValues>>:あなたは(IHeaderDictionaryIFormCollectionIQueryCollection)を言及

+0

private static IEnumerable<KeyValuePair<string, string[]>> Transform(IEnumerable<KeyValuePair<string, StringValues>> source) { foreach(var item in source) { yield return new KeyValuePair<string, string[]>(item.Key, item.Value.ToArray()); } } 

結局、あなたは次のようにメソッドを呼び出すことができます代わりにStringValues> dict'ですか?または 'IEnumerable > dict'? – mjwills

+0

'dict [key]'がここで文字列に変換されるとどう思いますか?辞書が複雑なクラスオブジェクトの束を保持しているとしたらどうなるでしょうか? – DavidG

+0

しかし、これらの3つのタイプはすべて、 'IEnumerable >'を実装しているので、本当に汎用メソッドは必要ありません。 – DavidG

答えて

4

これらのコレクションは、すべて同じインタフェースを実装します。

private static string ParseKeys(IEnumerable<KeyValuePair<string, StringValues>> values) 
{ 
    var sb = new StringBuilder(); 
    foreach (var value in values) 
    { 
     sb.AppendLine(value.Key + " = " + string.Join(", ", value.Value)); 
    } 
    return sb.ToString(); 
} 

をそして、あなたが以前にあったようにそれを呼び出す:代わりに、あなたはこのような何かを行うことができますが、一般的な方法を使用している

result.Headers = ParseKeys(context.Request.Headers); 
result.Form = ParseKeys(context.Request.Form); 
result.Query = ParseKeys(context.Request.Query); 
0

ができますが、ジェネリック型パラメータTを使用していません。限りIHeaderDictionaryIFormCollectionとして、両方のインターフェイスがそれを継承するので、それは、IEnumerable<KeyValuePair<string, string[]>>を受け入れるのに十分である:

private static string ParseKeys(IEnumerable<KeyValuePair<string, string[]>> dict) 
{ 
    var sb = new StringBuilder(); 
    foreach (var keyValuePair in dict) 
    { 
     sb.AppendLine(keyValuePair.Key + " = " + String.Join(", ", keyValuePair.Value)); 
    } 
    return sb.ToString(); 
} 

する限りIQueryCollectionに関しては、それはIEnumerable<KeyValuePair<string, StringValues>>あります。あなたが簡単にイテレータに必要な型にこれを変換することができます、あなたは `のIDictionary <文字列を取るために、` ParseKeys`を変更するとどうなりますか

result.Headers = ParseKeys(context.Request.Headers); 
result.Form = ParseKeys(context.Request.Form); 
result.Query = ParseKeys(Transform(context.Request.Query)); 
+0

IEnumerable > 'の上で' IEnumerable >を使用する理由は? – mjwills

+0

使用している[IFormCollection](https://msdn.microsoft.com/en-us/library/microsoft.owin.iformcollection(v = versus113).aspx)によって異なります。 – Sefe

+1

OPは.NET Coreを使用しています - それは 'IFormCollection'ではありません。 – mjwills

関連する問題