C# 铸造词典<;int,List<;用户>&燃气轮机;

C# 铸造词典<;int,List<;用户>&燃气轮机;,c#,.net,dictionary,casting,ienumerable,C#,.net,Dictionary,Casting,Ienumerable,将词典转换为词典最有效的方法是什么 这样做的原因是我有一个方法可以构建一个字典,但我不希望向调用代码返回一个可变的列表 我需要将此词典投影到新类型吗?您可以这样做: var userDictionary = new Dictionary<int, List<User>>(); IDictionary<int, IEnumerable<User>> newDictionary = userDictionary.ToDictionary(p =>

词典
转换为
词典
最有效的方法是什么

这样做的原因是我有一个方法可以构建一个
字典
,但我不希望向调用代码返回一个可变的
列表


我需要将此词典投影到新类型吗?

您可以这样做:

var userDictionary = new Dictionary<int, List<User>>();
IDictionary<int, IEnumerable<User>> newDictionary = userDictionary.ToDictionary(p => p.Key, p => p.Value.AsEnumerable());
var userDictionary=newdictionary();
IDictionary newDictionary=userDictionary.ToDictionary(p=>p.Key,p=>p.Value.AsEnumerable());

您需要将其投影到新词典中,例如

Dictionary<int, List<User>> myDictionary = ...;
Dictionary<int, IEnumerable<User>> resultingDictionary = myDictionary.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<User>)kvp.Value)
字典myDictionary=。。。;
Dictionary resultingDictionary=myDictionary.ToDictionary(kvp=>kvp.Key,kvp=>(IEnumerable)kvp.Value)
您无法执行从
字典
字典
的转换,因为如果可以,以下操作将是可能的:

Dictionary<int, List<User>> myDictionary = ...;
// Still a reference to the original dictionary
Dictionary<int, IEnumerable<User>> castDictionary = myDictionary;

// If the line above was possible, what would this do? (A HashSet<T> is not a List<T>)
castDictionary.Add(5, new HashSet<User>());
字典myDictionary=。。。;
//仍然是对原始词典的引用
Dictionary=myDictionary;
//如果上面这一行是可能的,这会有什么作用?(哈希集不是列表)
Add(5,newhashset());

您可能还需要查看接口上的协方差和逆变,以查看限制所在。

您可以返回一个
IEnumerable
,但在引擎盖下它将是一个
列表。开发人员可以将其转换为
列表
,并添加或删除项目

我想你在找

简单地说,它是一个nuget包,使我们能够使用/创建真正不可变的集合;这意味着任何集合的更改都不会反映回公开它们的内容

编辑:强制转换为IEnumerable不会授予不变性

给定Guilherme Oliveira的答案,您可以执行以下操作并向用户添加新用户

    var userDictionary = new Dictionary<int, List<User>>();
    userDictionary.Add(1, new List<User>
    {
        new User{ Name= "Joseph"},
    });
    IDictionary<int, IEnumerable<User>> newDictionary = userDictionary.ToDictionary(p => p.Key, p => p.Value.AsEnumerable());
    ((List<User>) newDictionary.Values.First()).Add(new User {Name = "Maria"});
    Console.WriteLine(newDictionary.Values.First().Count()); //now we have two users
var userDictionary=newdictionary();
添加(1,新列表
{
新用户{Name=“Joseph”},
});
IDictionary newDictionary=userDictionary.ToDictionary(p=>p.Key,p=>p.Value.AsEnumerable());
((List)newDictionary.Values.First()).Add(新用户{Name=“Maria”});
Console.WriteLine(newDictionary.Values.First().Count())//现在我们有两个用户

对于一个非常大的字典来说,这里的性能影响是什么?@davenewza:最好是对它进行基准测试;您的字典有多大?@LuisFilipe:可能有数百个键,每个键都可以与数百个用户的列表相关联。
p.Value.AsEnumerable()
将不涉及任何费用,因为它返回对原始列表的引用。为数百个键复制一本词典根本不会花费太多时间。我刚刚在0.05秒内复制了一本包含1000000个条目的词典。请阅读我的更新答案:返回IEnumerable并不授予不变性,从您的问题来看,这似乎就是您正在寻找的内容。词典是否需要将
列表
作为值保存?您可以填写
列表
并将其添加到
字典
。如果可以,您可以编写一个方法,返回IEnumerable,该方法的索引将查找调用者。这样,您就不必一次转换所有内容,而只需按每个索引请求进行转换。将其设置为
IEnumerable
并不能防止可变性。如果要保证调用者不能更改基础列表,您需要一个不可变集合或“冻结”集合。实际上,当您将
myDictionary
设置为
castdirectionary
时,您并没有强制转换它。如果要将值更改为另一种类型,则必须使用
AsEnumerable()
进行强制转换。请阅读该示例上方的行和该赋值下方的注释,我说了是否可能,但事实并非如此。