简体   繁体   中英

C# Generics constraint with Interface to a method

probably the title is not right but i can't figure out something more precise.

I have this class:


    Transport<T> where T: ISomething

I have another class where i can have my "Transport" class with his generics that implement my ISomething. Like This:


    public class Route 
    {
        Transport<ISomething> Transport;
        public Route(Transport<ISomething> t)
        {
            Transport = t;
        }
    }

I want to be able to call my constructor


    Transport<Potatoes> myTransport = GetAllPotatoes();
    
    Route myRoute = new Route(myTransport);

Is there a way to do this? I'm new to generics and (as non native english speaker) i can't use the right keywords to find the answer myself.

Thanks.

EDIT for clarity: Potatoes implements ISomething.

You can make the route generic as well, like so:

public class Route<T>
    {
        Transport<T> Transport;
        public Route(Transport<T> t)
        {
            Transport = t;
        }
    }

Then you can create a route as

   Transport<Potatoes> myTransport = GetAllPotatoes();
    
    Route<Potatoes> myRoute = new Route<Potatoes>(myTransport);

I guess however, that's not what you want, because you want to be able to create routes that are not generic. In this case, you need to have a non-generic base class of either Route or Transport .

For instance:

public interface ITransport {}

public class Transport<T> : ITransport 
where T: ISomething
{
}

public class Route
    {
        ITransport Transport;
        public Route(ITransport t)
        {
            Transport = t;
        }
    }

You can make it with a covariant interface... in your case:

public interface ISomething {
}

public interface ITransport<out T> where T : ISomething
{
}

public class Transport<T> : ITransport<T> where T: ISomething
{
}

public class Potatoes : ISomething {
}

public class Route 
{
  ITransport<ISomething> Transport;
  public Route(ITransport<ISomething> t)
  {
    Transport = t;
   }
}

public class Program
{
    public static void Main()
    {
        Transport<Potatoes> myTransport = null /* or getAllPotatoes */;   
        Route myRoute = new Route(myTransport);
    }
}

Note that Route now takes an ITransport<T> , not a Transport<T> .

Covariance in classes doesn't work, you need an interface for that.

This doesn't do anything, but just so you see it compiles: https://dotnetfiddle.net/T2Yd8N

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