Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Friday, May 23, 2008 3:53 PM
Class1 contains the RetrieveAll method that I'm trying to call from Class2. I just can't get this thing happy as it's not like the types I put in for my Generic list I guess. I've glossed over the implementation of Class1 and it's returning an IEnumerable I guess:
Class1 (hhDbRoleProvider):
namespace xxx.hh.Business.Entities
{
public class hhDbRoleProvider : IRoleProvider
{
public IRole New(string roleName)
{
return new Role(this)
{
RoleName = roleName,
Description = string.Empty
};
}
public IEnumerable<IROLE> RetrieveAllRoles()
{
List<IRole> roles = new List<IRole>();
using (IDataReaderEnumerable<ROLE> dalRoles = Role.RetrieveAll())
foreach (Role dalRole in dalRoles)
roles.Add(new Role(dalRole));
return roles;
}
}
}
Class2 (HHRoleProvider)
namespace xxx.hh.Common.Roles
{
class HHRoleProvider : RoleProviderBase
{
public override Configuration.Roles.Role[] GetRoles()
{
// Grab all the roles from the DB
hhDbRoleProvider roleProvider;
List<xxx.BusinessInterfaces.Security.IRole> hhRoles = roleProvider.RetrieveAllRoles();....
The error is on the last line and I cannot figure out how the hell to get it to be "happy":
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<xxx.BusinessInterfaces.Security.IRole>' to 'System.Collections.Generic.List<xxx.BusinessInterfaces.Security.IRole>'. An explicit conversion exists (are you missing a cast?)
All replies (9)
Friday, May 23, 2008 4:04 PM ✅Answered
You can't cast directly from IEnumerable<> to List<> because they aren't the same thing.
You can either use LINQ's ToList() method, or instantiate a new List<>:
List<xxx.BusinessInterfaces.Security.IRole> hhRoles = new List<xxx.BusinessInterfaces.Security.IRole>
(roleProvider.RetrieveAllRoles());
Friday, May 23, 2008 5:12 PM ✅Answered
If the method signature says IEnumerable, then that's what it is returning. List<T> can be implicitly cast to IEnumerable<T>, but you'll have to explicitly cast to go from IEnumerable<T> to List<T>:
IEnumerable<String> ienum = new List<String>();
List<String> list = (List<String>)ienum;
Friday, May 23, 2008 5:45 PM ✅Answered
You've declared it, but you haven't assigned a value to it or instantiated it.
hhDbRoleProvider roleProvider = new hhDbRoleProvider();
Or whatever constructor or method you have of instantiating hhDbRoleProvider.
Also, just out of curiosity, why are you creating your own role provider instead of just using the one that comes with ASP.NET?
Friday, May 23, 2008 5:04 PM
I'm confused (understand that I get Generic lists but new to IEnumerable stuff and complex casting in situations like this)...and I also updated the RetrieveAllRoles() implementation in class 1 becasue the stupid editor in here took out half of what was there which was this:
List<IRole> roles = new List<IRole>();
So since RetrieveAllRoles is returning a Generic List of IRole, I still do not get why I can't set it to another Generic list of IRole in my Class 2. However the method signature on that method in class 1 says IEnumerable so what the hell is it returning? Is it returning a generic list of IRole or simply an IEnumerable? I don't see how this works. I know that IEnumerable lets you iterate over a list. But I guess I don't get this casting scenario.
Friday, May 23, 2008 5:22 PM
Thanks, I'll have to research IEnumerable a bit more to really get this. I guess I also don't understand how it's returning an IEnumerable<> besides the method signature saying it's returning an IEnumerable when it's showing me that it's returning a generic list of IRole. So somehow the compiler pushes in An IEnumerable<IRole>...I just don't get that. The return statement in that method is saying it's returning List<IRole> but method signature doesn't say List<IRole> it says IEnumerable. What are the symantics of that?
But moving on, I now get this:
hhDbRoleProvider roleProvider;
List<xxx.BusinessInterfaces.Security.IRole> hhRoles = new List<xxx.BusinessInterfaces.Security.IRole>(roleProvider.RetrieveAllRoles());
I also tried:
hhDbRoleProvider roleProvider;
List<xxx.BusinessInterfaces.Security.IRole> hhRoles = new List<xxx.BusinessInterfaces.Security.IRole>();
hhRoles = (List<xxx.BusinessInterfaces.Security.IRole>)roleProvider.RetrieveAllRoles();
Either way I still get this error: Use of unassigned local variable 'roleProvider'
What is it talking about, I DID use it.
Friday, May 23, 2008 6:14 PM
because the one that comes with .NET doesn't support what we're doing. Our portal is very advanced and we're not going to extend the asp.net membership for this. We're using ASP.NET MVC and this provider will hook into our CMS system. I can't really explain, it's that complicated of a system that we can't use the membership provider for our needs.
Friday, May 23, 2008 6:15 PM
There is an implicit constructor I guess since the dude did not define one in class1
Friday, May 23, 2008 6:19 PM
In the end this seems to work:
hhDbRoleProvider roleProvider = new hhDbRoleProvider();
List<xxx.BusinessInterfaces.Security.IRole> hhRoles = (List<xxx.BusinessInterfaces.Security.IRole>)roleProvider.RetrieveAllRoles();
Thanks for your help. I have a long way to go to understanding casting for this and IEnumerable stuff.
Friday, May 23, 2008 9:24 PM
It is a little tricky - I've been doing C# for a couple of years and I'm still not completely clear on exactly what IEnumerable does.
As far as I can tell, List<T> is pretty much a strongly typed array with a bunch of really handy extra functionality. IEnumerable<T> isn't an array, but rather a non-indexed collection of objects that can be enumerated (meaning looped through). IEnumerable<T> is the most basic interface that must be implemented by an object for it to support foreach.
If you use LINQ, or are at least familiar with it, it makes it a little easier to understand.
When you create a LINQ query or use a lambda expression, the result is returned as an IEnumerable<T> (or IQueryable<T>, which is nearly the same thing I believe). However, you can think of that as just a query. It doesn't actually contain any data itself, it's just sort of a pointer to it.
The expression or query isn't actually executed until you iterate through it, or call a method like ToList(), ToArray() or ToDictionary(), which causes it to be enumerated.
I hope that helps... good luck! :)