1

Here is my code:

public interface ICar
{
    CarModel Property { get; set; }
    CarModel Method();
}

public Car<T> : ICar where T : CarModel 
{
    T Property { get; set; }
    T Method()
    {
        //Do Stuff
    }
}

I have implemented the interface in my Car<T> class with generic constraints but it doesn't compile with the following error:

Compilation error (line 18, col 15): 'Car<T>' does not implement interface member 'ICar.Property'. 'Car<T>.Property' cannot implement 'ICar.Property' because it does not have the matching return type of 'CarModel'.
Compilation error (line 18, col 15): 'Car<T>' does not implement interface member 'ICar.Method()'. 'Car<T>.Method()' cannot implement 'ICar.Method()' because it does not have the matching return type of 'CarModel'.

I also need the interface to be non generic, here is a .Net fiddle: https://dotnetfiddle.net/m1jDnB

The only work around I have for this is to wrap the property or method with something that implements the interface as it wants it BUT I dont want to do this. ie:

public Car<T> : ICar where T : CarModel 
{
    T Property { get; set; }
    T Method()
    {
        //Do Stuff
    }

    CarModel ICar.Property 
    { 
      get {return Property; }
      set {Property = (CarModel)value; }
    }

    CarModel ICar.Method()
    {
        return (CarModel)Method();
    }
}

Is there a better way?

5
  • What was the build error, looks like you implentation method does not return a value. Commented Sep 12, 2016 at 2:52
  • Is Car<MyCarModel> allowed in your design? (MyCarModel inherits from CarModel) Commented Sep 12, 2016 at 6:04
  • @markmnl, sorry my fault in the write up made changes as above Commented Sep 13, 2016 at 23:47
  • @DannyChen Check out the .Net fiddle it shows what you are asking and it still errors Commented Sep 14, 2016 at 0:04
  • The thing you don't want to do is the best way to accomplish what you say you want to accomplish. (except that the setter should have Property = (T)value; instead of Property = (CarModel)value. However, that does increase the chances of a run-time error such as the one shown in @recursive's answer Commented Sep 14, 2016 at 20:56

1 Answer 1

1

This can't be done. If the compiler did allow you to do it, the result wouldn't be type safe. If the types were allowed to compile the way you wanted, then this code would be permitted by the compiler.

public class CarModel {
    public string Name { get; set; }
}

public class Toyota : CarModel {
    public string SpecialToyotaNumber { get; set; }
}

public class Honda : CarModel { }

public interface ICar {
    CarModel Property { get; set; }
    CarModel Method();
}

public class Car<T> : ICar where T : CarModel {
    public T Property { get; set; }

    public T Method() {
        return (T)new CarModel();
    }
}

public class Main {
    public void Run() {
        ICar car = new Car<Toyota>();
        car.Property = new Honda(); // the concrete property is declared Toyota
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.