I need to pass a variable of type IDictionary<Guid, IEnumerable<Guid>>
into a method. When I use the following code:
var userGroupDictionary = _selectedUsers.ToDictionary(u => u.UserGuid, u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList());
I get the following error:
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>>'
When I iterate through my collection it works however:
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());
}
Any ideas what's going on? Is the compiler unable to tell that Dictionary<Guid, List<Guid>>
satisfies IDictionary<Guid, IEnumerable<Guid>>
The problem is that type inference is returning a Dictionary<Guid, List<Guid>>
, which is the wrong type for the method you want to call. There's a bit more to it than that, but it involves a type variance discussion. You can solve the problem with the AsEnumerable extension:
var userGroupDictionary = _selectedUsers
.ToDictionary(
u => u.UserGuid,
u => u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList().AsEnumerable());
...or you can do a simple cast, as in the following:
var userGroupDictionary = _selectedUsers
.ToDictionary(
u => u.UserGuid,
u => (IEnumerable<Guid>)u.GroupUsers.Select(gu => gu.Group.GroupGuid).ToList());
If you merely omit the ToList()
as others have recommended, the type inference will indeed render the type you expect, but the IEnumerable
returned will have deferred-execution which may or may not be an issue for you. Leaving ToList
in there but doing a cast of sorts will immediately evaluate the items instead of lazily evaluating them at the time of iteration.
For more detail on deferred execution, see the "laziness" (think lazy-evaluation) section of Jon Skeet's Edulinq series, part 44