bobblez
bobblez

Reputation: 1370

Confused about interfaces and implementation

The case is very simple, I have this interface

public interface IHasNext
{
    IHasNext NextItem { get; set; }
}

and then I attempt to implement it like so:

public class Item : IHasNext
{
    public int Id { get; set; }
    Item NextItem { get; set; }
}

but this won't work because the property NextItem of the implementation is not of the same type (even if the type implements the interface). So could someone kindly explain me the reason for this not working, when you can quite liberally swap types for interfaces they implement even as type parameters (at least on IEnumerable and IQueryable).

Upvotes: 3

Views: 105

Answers (3)

Charles Bretana
Charles Bretana

Reputation: 146409

Why aren't you implementing it as:

 public class Item : IHasNext
 {
    public int Id { get; set; }
    IHasNext NextItem { get; set; }
 }

? This interface could be on any class that implements IHasNext.

But better still is to make it generic

public interface IHasNext<T>
{
    T NextItem { get; set; }
}

 public class Item : IHasNext<Item>
 {
    public int Id { get; set; }
    Item NextItem { get; set; }
 }

Upvotes: 0

Paddy
Paddy

Reputation: 33857

The interface states that the property must be of type IHasNext, your code should be:

public class Item : IHasNext
{
    public int Id { get; set; }
    IHasNext NextItem { get; set; }
}

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499760

Consider this code:

public class BadItem : IHasNext
{
    public IHasNext { get; set; }
}

Now:

IHasNext item = new Item();
item.NextItem = new BadItem();

That's perfectly valid... but what would you expect it to do on the Item class? Its NextItem property is of type Item, so it doesn't know what to do with a BadItem...

Basically, doing this is unsafe.

You may want to make your interface generic:

public interface IHasNext<T> where T : IHasNext<T>
{
    T NextItem { get; set; }
}

public class Item : IHasNext<Item>
{
    public int Id { get; set; }
    IHasNext<Item> NextItem { get; set; }
}

Upvotes: 9

Related Questions