簡體   English   中英

如何使用一種通用方法遍歷不同類型的詞典?

[英]How can I iterate through different types of dictionaries using one generic method?

我有一個HttpContext context並且遍歷其一些Request屬性來收集信息。 目前,我是這樣進行的:

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();
}

並這樣稱呼它:

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

但是我遇到了這樣的錯誤: cannot convert from 'Microsoft.AspNetCore.Http.IHeaderDictionary' to 'System.Collections.Generic.IDictionary<object, object>'

我嘗試了各種組合,但仍然無法避免錯誤。 我是在這里嘗試做不可能的事情,還是在做我想做的簡單事情?

您提到的那些集合( IHeaderDictionaryIFormCollectionIQueryCollection )都實現相同的接口: IEnumerable<KeyValuePair<string, StringValues>>因此在這里您不需要通用方法。 相反,您可以執行以下操作:

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);

您正在使用泛型方法,但沒有使用泛型類型參數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>> 您可以使用迭代器輕松將其轉換為所需的類型:

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());
    }
}

最終,您可以像下面這樣調用方法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM