简体   繁体   中英

c# - How to implement a non generic interface in a generic class with constraints

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?

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM