Thomas
Thomas

Reputation: 232

Type safety through inheritance

This is probably an easy question, however i could not find a solution so far...

Let's say I have an Interface "IEntity", that is implemented by several other interfaces. What I want is that each of these interfaces implement a method with the return type of themselves. For example the Entity "Car" should return "ICar", while the Entity "Person" should return "IPerson". I've tried to implement this functionality with generic types but didn't find a really acceptable solution.

Hope you can help me, thanks in advance.

Upvotes: 0

Views: 153

Answers (4)

niculare
niculare

Reputation: 3687

Just add a return type for the method in cause which is a superclass of all the possible types returned by the methods in derived interfaces. For your case:

interface IEntity {
  IEntity SomeMethod();
}

Upvotes: 0

Chris Sinclair
Chris Sinclair

Reputation: 23208

Well you can do this fairly easily with generics, but I'm assuming that your code somewhere would deal with an IEntity and not know about the underlying generic type at compile-time. If so, then you can declare two interfaces as so:

public interface IEntity<T> : IEntity
{
    new T GetThis();
}

public interface IEntity
{
    object GetThis();
}

Then your Car might look something like this:

public class Car : ICar, IEntity<ICar>
{
    public ICar GetThis()
    {
        Console.WriteLine("Generic GetThis called");
        return this;
    }

    object IEntity.GetThis()
    {
        Console.WriteLine("Non-generic GetThis called");
        return this;
    }
}

This uses Explicit Interface Implementation, so if the calling code knows it's a Car (or rather, an IEntity<ICar>) then it will leverage the the generic version. If it only knows it as an IEntity then it will leverage the non-generic version.

So some code that might leverage this:

public static T SomeMethod<T>(IEntity<T> entity)
{
    T target = entity.GetThis(); //Generic GetThis called
    return target;
}

public static object SomeNonGenericMethod(IEntity entity)
{
    object target = entity.GetThis(); //Non-generic GetThis called
    return target;
}

Car car = new Car();
ICar icar = SomeMethod<ICar>(car);

IEntity someEntity = new Car();
object obj = SomeNonGenericMethod(someEntity);

Upvotes: 1

Drew Noakes
Drew Noakes

Reputation: 310897

I'm not not completely clear on what you're after, but this sounds close and is simple.

interface IEntity<T>
{
    T Value { get; }
}

class Car : IEntity<ICar>
{
    ICar Value { get; }
}

class Person : IEntity<IPerson>
{
    IPerson Value { get; }
}

Do you need something more complex?

Upvotes: 1

Lee
Lee

Reputation: 144136

The usual way to do this is with the 'recurring template pattern':

interface IEntity<T> where T : IEntity<T>
{
    T GetSelf();
}

Your entity types then implement this interface, using their own type as the generic parameter T:

public class Car : IEntity<Car>
{
    Car GetSelf() { return this; }
}

Upvotes: 1

Related Questions