使用Linq对象,ToDictionary方法不满足类型要求

时间:2012-03-09 22:01:35

标签: c# linq casting todictionary

我需要将类型IDictionary<Guid, IEnumerable<Guid>>的变量传递给方法。当我使用以下代码时:

var userGroupDictionary = _selectedUsers.ToDictionary(u => u.UserGuid, u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList());

我收到以下错误:

cannot convert from System.Collections.Generic.Dictionary<System.Guid,System.Collections.Generic.List<System.Guid>>' to 'System.Collections.Generic.IDictionary<System.Guid,System.Collections.Generic.IEnumerable<System.Guid>>'

当我遍历我的收藏时,它会起作用:

var userGroupDictionary = new Dictionary<Guid, IEnumerable<Guid>>();
foreach (var user in _selectedUsers.Where(user => !userGroupDictionary.ContainsKey(user.UserGuid)))
{
    userGroupDictionary.Add(user.UserGuid, user.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList());
}

任何想法发生了什么?编译器无法判断Dictionary<Guid, List<Guid>>是否满足IDictionary<Guid, IEnumerable<Guid>>

4 个答案:

答案 0 :(得分:1)

下面的行会创建一个字典,其中的键为Guid类型,值为List<Guid>

_selectedUsers.ToDictionary(
                   u => u.UserGuid, 
                   u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList()
                   );

所以只需删除.ToList()就可以了,u.GroupUsers.Select()本身会返回IEnumerable<Guid>

你可以在List实现IEnumerable之后迭代这两个值,这应该满足foreach迭代器。

答案 1 :(得分:1)

问题是类型推断返回Dictionary<Guid, List<Guid>>,这是您要调用的方法的错误类型。除此之外还有更多内容,但它涉及类型方差讨论。您可以使用AsEnumerable扩展程序解决问题:

var userGroupDictionary = _selectedUsers
    .ToDictionary(
        u => u.UserGuid,
        u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList().AsEnumerable());

...或者您可以进行简单的演员表,如下所示:

var userGroupDictionary = _selectedUsers
    .ToDictionary(
        u => u.UserGuid,
        u => (IEnumerable<Guid>)u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList());

如果您只是忽略其他人推荐的ToList(),那么类型推断确实会呈现您期望的类型,但返回的IEnumerable将具有延迟执行,这可能是也可能不是问题为了你。将ToList留在那里但是进行各种类型的投射将立即评估项目,而不是在迭代时懒惰地评估它们。

有关延迟执行的更多详细信息,请参阅Jon Skeet's Edulinq series, part 44

的“懒惰”(认为懒惰评估)部分

答案 2 :(得分:0)

  

编译器无法判断Dictionary<Guid, List<Guid>>是否满足IDictionary<Guid, IEnumerable<Guid>>

不,编译器能够告诉Dictionary<Guid, List<Guid>> 满足IDictionary<Guid, IEnumerable<Guid>>。例如,后者提供了一种方法Add(Guid, IEnumerable<Guid>),您的词典无法支持该方法。

您可以在词典中明确说明允许的值,例如使用

_selectedUsers.ToDictionary<User, Guid, IEnumerable<Guid>>(
    u => u.UserGuid,
    u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList())

答案 3 :(得分:0)

我认为所有u.GroupUsers都有相同的groupID。你可以得到第一个groupID, 如果可以在用户类上访问groupID属性。您应该使用GroupID。 像_selectedUsers.ToDictionary(u=>u.UserGuid,u.GroupID);一样 如果您无法访问用户类的GroupId。 使用:

_selectedUsers.ToDictionary(
                   u => u.UserGuid, 
                   u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).First());