Reputation: 330
I had wrote this codes:
public interface IUser
{
string Username { get; set; }
string Password { get; set; }
IList<IRole> Roles { get; set; }
}
public interface IRole
{
string Name { get; set; }
IList<IUser> Users { get; set; }
}
public class User : IUser
{
public string Username { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IList<Role> Roles { get; set; }
}
public class Role : IRole
{
public string Name { get; set; }
public IList<User> Users { get; set; }
}
I think in logic there is no problem. Because User class is type of IUser interface, and Role class is type of IRole interface too. But it doesn't compile. Actually Compiler doesn't recognize that classes are type of their interfaces. The question is why is this happening and what to do?
Upvotes: 1
Views: 625
Reputation: 23103
If you want to use the specific types you could use generics:
public interface IUser
{
string Username { get; set; }
string Password { get; set; }
}
public interface IUser<TRole> : IUser where TRole : IRole
{
IList<TRole> Roles { get; set; }
}
public interface IRole
{
string Name { get; set; }
}
public interface IRole<TUser> : IRole where TUser : IUser
{
IList<TUser> Users { get; set; }
}
public class User : IUser<Role>
{
public string Username { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IList<Role> Roles { get; set; }
}
public class Role : IRole<User>
{
public string Name { get; set; }
public IList<User> Users { get; set; }
}
Upvotes: 2
Reputation: 45135
Consider this, you have:
public interface IRole
{
string Name { get; set; }
IList<IUser> Users { get; set; }
}
And then you have:
public class Role : IRole<User>
{
public string Name { get; set; }
public IList<User> Users { get; set; }
}
Now imagine I added:
public class SomeOtherUser : IUser
{
//...
}
I could do this (ignoring for a moment the uninitialized list):
var role = new Role();
var iRole = (IRole)role;
iRole.Users.Add(new SomeOtherUser());
But that should not, and cannot work. Because SomeOtherUser
isn't a User
. They both implement IUser
, but you definition in the Role
class of the Users
property is IList<User>
not IList<IUser>
.
So you have to change Role
to implement the interface you gave it:
public class Role : IRole<User>
{
public string Name { get; set; }
public IList<IUser> Users { get; set; }
}
And you'll have to cast the elements in Users
when you use them if you need extra properties that are part of User
but not IUser
. Or you could create another property to provide direct access to the underlying IList<User>
, but the you'll might need to cast your IRole
to a Role
. Or if you can edit the the interface, using generics as @ChrFin suggested is a great solution.
Upvotes: 3
Reputation: 23721
Ignoring the typo of class
as mentioned by a commenter, your classes do not implement the interfaces completely, specifically in Role
, you need:
public IList<IUser> Users { get; set; }
Rather than:
public IList<User> Users { get; set; }
Similarly, in the class User
you need:
public IList<IRole> Roles { get; set; }
instead of:
public IList<Role> Roles { get; set; }
Upvotes: 1
Reputation: 68400
Interface must match exactly and you hace a mismatch on properties Roles
and Users
On Role
, you have to replace this
public IList<User> Users { get; set; }
by this
public IList<IUser> Users { get; set; }
And something similar for User
. Replace this
public IList<Role> Roles { get; set; }
by this
public IList<IRole> Roles { get; set; }
Upvotes: 3