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:…or you can do a simple cast, as in the following:
If you merely omit the
ToList()as others have recommended, the type inference will indeed render the type you expect, but theIEnumerablereturned will have deferred-execution which may or may not be an issue for you. LeavingToListin 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