我有下一个功能:
private static Dictionary<string, object> FromCookies(HttpCookieCollection cc)
{
return (from string cookie in cc.AllKeys select new { Name = cookie, Value = (object)cc[cookie] }).ToDictionary(kvp => kvp.Name, kvp => kvp.Value, StringComparer.InvariantCultureIgnoreCase);
}
但是当我构建时,编译器说我:
System.ArgumentException: An item with the same key has already been added.
但我需要重写这个项目。我怎么能用LINQ做到这一点?我很抱歉我的愚蠢问题,如果这么容易回答。
答案 0 :(得分:1)
我可能会犯错,但我认为你不能使用LINQ来做到这一点。 return语句创建一个新的字典,该字典将从cookie集合中的对象创建。如果此集合包含多个具有相同名称的对象,则表明您遇到了问题。
我认为实现这一目标的最佳方法是迭代cookie集合,手动为字典创建对象,并使用索引器语法将它们设置在字典中:
dictionary[cookiename] = cookieValue;
干杯!
亚历
答案 1 :(得分:0)
您可以选择 distinct Cookie以避免重复的字典键。但是,当然,结果字典中只有一个值。即如果您有"Hello"
,"hello"
和"HELLO"
等Cookie,则如果您使用忽略大小写比较,则无法放置所有这些键。下面的解决方案仅选择与忽略大小写相同的第一个值(在这种情况下将仅添加"Hello"
个键):
return (from string cookie in cc.AllKeys.Distinct(StringComparer.InvariantCultureIgnoreCase) // here
select new {
Name = cookie,
Value = (object)cc[cookie]
})
.ToDictionary(kvp => kvp.Name, kvp => kvp.Value);
BTW代码可以简化为
return cc.AllKeys // use .Cast<string>() if need
.Distinct(StringComparer.InvariantCultureIgnoreCase)
.ToDictionary(cookie => cookie,
cookie => (object)cc[cookie]);
因此,您将避免匿名对象的创建。
答案 2 :(得分:0)
也许你有重复的名字,你可以先使用GroupBy
StringComparer
{/ 1>}
private static Dictionary<string, object> FromCookies(HttpCookieCollection cc)
{
var result = cc.AllKeys
.Select(cookie => new { Name = cookie, Value = (object)cc[cookie] })
.GroupBy(x => x.Name, StringComparer.InvariantCultureIgnoreCase)
.ToDictionary(g => g.Key, g => g.First().Value, StringComparer.InvariantCultureIgnoreCase);
return result;
}
我从重复项中取出第一个值。但你可以改变逻辑。
答案 3 :(得分:0)
您总是可以使用IEnumerable的KeyValuePairs,这将允许具有相同键的多个项目。你不会丢失任何数据:
private static IEnumerable<KeyValuePair<string, object>> FromCookies(HttpCookieCollection cc)
{
return (from string cookie in cc.AllKeys select new KeyValuePair<string,object>(cookie, cc[cookie]));
}