Fred Johnson
Fred Johnson

Reputation: 2695

C#: Interface to force list of items inheriting the interface

I have the following interface:

IMyInterface
{
     IList<IMyInterface> MyList { get; set; }
     int X { get; set; }
     int Y { get; set; }
}

I want to force the class implementing this interface to have a list "MyList" with a list of other items also implementing IMyInterface. How do I do this?

I get errors if I try the following:

public class MyClass: IMyInterface
{
    public int X { get; set; }
    public int Y { get; set; }
    public List<MyClass> MyList { get; set; }
}

Upvotes: 4

Views: 102

Answers (3)

juharr
juharr

Reputation: 32266

If you want the items of MyList to be of the implementing type class you have to use generics. You should also use a restraint to force T to be a type that implements the interface. And MyList still has to be a IList in the implementing class.

IMyInterface<T> where T : IMyInterface<T>
{
     IList<T> MyList { get; set; }
     int X { get; set; }
     int Y { get; set; }
}

public class MyClass: IMyInterface<MyClass>
{
    public int X { get; set; }
    public int Y { get; set; }
    public IList<MyClass> MyList { get; set; }
}

This doesn't stop someone from doing something like

public class AnotherClass: IMyInterface<MyClass>
{
    public int X { get; set; }
    public int Y { get; set; }
    public IList<MyClass> MyList { get; set; }
}

But it's as close as you can get.

Upvotes: 4

Nikhil Agrawal
Nikhil Agrawal

Reputation: 48558

The other answers are what you want but still you cannot FORCE the user to do. You are only forcing user that the implementing class will be implementing IMyInterface and I can still do

public interface IMyInterface<T> where T : IMyInterface<T>
{
    IList<T> MyList { get; set; }
    int X { get; set; }
    int Y { get; set; }
}

public class MyClass : IMyInterface<MyClass>
{
    public int X { get; set; }
    public int Y { get; set; }
    public IList<MyClass> MyList { get; set; }
}

public class FooBar : IMyInterface<MyClass>
{
    public IList<MyClass> MyList { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
}

Here FooBar satisfies all the rules, still MyList is of Type IList<MyClass> but not of type ILIst<FooBar>.

Upvotes: 0

Pawel Troka
Pawel Troka

Reputation: 853

public interface IMyInterface<T>
{
    IList<T> MyList { get; set; }
    int X { get; set; }
    int Y { get; set; }
}
public class MyClass : IMyInterface<MyClass>
{
    public int X { get; set; }
    public int Y { get; set; }
    public IList<MyClass> MyList { get; set; }
}

Or you can go for something like this:

public interface IMyInterface<T>
{
    List<T> MyList { get; }
    int X { get; set; }
    int Y { get; set; }
}
public class MyClass : IMyInterface<MyClass>
{
    public int X { get; set; }
    public int Y { get; set; }
    public List<MyClass> MyList { get; }
}

I would actually prefer for my interface to not define setter for MyList since only getter is required from outside as you most like would like to implement logic of getting items to this list within MyClass implementation.

Upvotes: 1

Related Questions