Sorry if the title is not very descriptive. I didn't know how to describe this.
First, I created an interface like this:
public interface IUser {}
Then implemented it in several classes like this:
public class Student : IUser {}
public class Teacher : IUser {}
Then I created an Interface that required the first interface
public class IUsers
{
List<IUser> Users {get; set;}
}
Then I created a Class that used the second interface, but used one of the Members of the first interface to for fill the contract.
public class Students : IUsers
{
List<Student> Users {get; set;}
}
The problem is the last one I wanted to constrain the list to just one implementation of the interface, but still need to maintain the interface for data compatibility. When I do this I get an error saying I'm not implementing the interface. I thought that since Student implemented the interface it would for fill the obligation, but it doesn't seem to. Is this correct or am I doing something else wrong
You need to say what kind of users your collection supports. Suppose your code were valid - then this would compile:
IUsers users = new Students();
// What would this do at execution time? It's not safe!
users.Users.Add(new Teacher());
After all, that's just adding a Teacher to a List<IUser>, right? But in Students, the Users property is a List<Student>, so that can't accept a teacher.
The best approach is probably to make your IUsers interface generic in the type of user it accepts:
public class IUsers<TUser> where TUser : IUser
{
List<TUser> Users {get; set;}
}
Then your Students class would implement IUsers<Student>, and the property would be fine.
At that point, the problematic example at the top of the answer would fail to compile:
// This is fine
IUsers<Student> users = new Students();
// This won't compile, because users.Users is of type List<Student>, and you can't add
// a Teacher to that.
users.Users.Add(new Teacher());
Based on the code, to me the sample appears to indicate you would like to maintain separate implementations for your users, then return the desired implementation.
public interface IStudentFactory
{
IUser Create();
}
public class StudentFactory
{
public IUser Create() => new StudentContext();
}
Then based on your implementation inside your interface of IUser, you could connect to your data store to manage those types of user.
var context = new StudentFactory().Create())
var students = context.GetAllStudents();
context.Students.Add(new Student() { });
The approach I provided is under the notion that you want to be able to access this information about different types of users, persist, and manage. Your example showed a primitive collection where you are adding, potentially handling other functionality, but I imagine you are working more towards something a bit more consistent.
I may be off the mark for your intent, but that is how I interpreted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With