【问题标题】:C# Generics constraint with Interface to a method带有方法接口的 C# 泛型约束
【发布时间】:2021-07-01 06:40:22
【问题描述】:

可能标题不正确,但我想不出更准确的东西。

我有这门课:


    Transport<T> where T: ISomething

我有另一个类,我可以在其中使用我的“Transport”类和实现我的 ISomething 的泛型。像这样:


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

我希望能够调用我的构造函数


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

有没有办法做到这一点?我是泛型新手,并且(作为非英语母语人士)我自己无法使用正确的关键字来找到答案。

谢谢。

为清楚起见编辑: Potatoes 实现了 ISomething。

【问题讨论】:

  • 你能显示你在Transport类中有哪些成员吗?
  • Transport&lt;Potatoes&gt;不是Transport&lt;ISomething&gt;。泛型参数化不会导致构造类型获得与原始类型相同的继承/实现关系。
  • 你的 Potatoes 课程由什么组成?它也是从 ISomething 接口实现的?
  • 我实际上认为您在这里根本不需要泛型。你TransportISomething 无论如何都在你的Route 上。
  • 当然,我的 Potatoes 类实现了 ISomething

标签: c# generics interface constraints


【解决方案1】:

您可以使用协变接口来实现...在您的情况下:

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

请注意,Route 现在采用 ITransport&lt;T&gt;,而不是 Transport&lt;T&gt;

类中的协方差不起作用,您需要一个接口。

这并没有做任何事情,只是让你看到它编译:https://dotnetfiddle.net/T2Yd8N

【讨论】:

    【解决方案2】:

    您也可以将路由设为通用,如下所示:

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

    然后你可以创建一个路由为

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

    但是,我想这不是您想要的,因为您希望能够创建非通用的路由。在这种情况下,您需要有一个非泛型基类 RouteTransport

    例如:

    public interface ITransport {}
    
    public class Transport<T> : ITransport 
    where T: ISomething
    {
    }
    
    public class Route
        {
            ITransport Transport;
            public Route(ITransport t)
            {
                Transport = t;
            }
        }
    

    【讨论】:

    • 我需要的是为我的 Route 构造函数提供一个 Transport。也许我的方法完全不正确。由于我的“运输”品种,我希望我的路线尽可能灵活
    • 问题是 Route 是否需要访问 ISomething 或 Transport 的属性/方法。如果路由不需要知道实际的 ISomething,那么上面的建议应该对你有用。
    • 是的,它应该使用 ISomething 方法和属性
    • 你的交通工具知道 ISomething,你的路线可能不应该。如果 Route 需要访问 ISomething 的字段,请将相应的包装方法添加到 Transport。你也可以让 Transport implement ISomething.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    相关资源
    最近更新 更多