【问题标题】:Interface method with interface parameter, where implementations have their own class as parameter带有接口参数的接口方法,其中实现有自己的类作为参数
【发布时间】:2019-07-18 02:16:12
【问题描述】:

假设我有如下界面:

interface IShape
{
    bool Intersect(IShape shape);
}

那我想要下面的具体实现:

class Circle : IShape
{
    bool Intersect(Circle shape) {...}
}

class Rectangle : IShape
{
    bool Intersect(Rectangle shape) {...}
}

在 C# 中是否有任何聪明的方法可以在不使用泛型的情况下做到这一点? 即任何不是这样的方式:

interface IShape<T> where T : IShape<T>
{
    bool Intersect(T shape);
}

class Circle : IShape<Circle>
{
    bool Intersect(Circle shape) {...}
}

【问题讨论】:

  • 为什么不想使用泛型?
  • 在编译时,没有办法在 C# 中表达“返回或采用与声明类型相同类型的参数的方法”。您最好的选择是采用IShape in 参数并在运行时检查实际类型,这也允许您与多种形状类型相交。
  • @Sweeper 因为如果我使用泛型,我认为没有办法声明泛型IShape。我必须声明一个IShape&lt;Rectangle&gt; 或IShape&lt;Circle&gt;,但我不能有一个“任何”IShape。
  • @DadeKuma 假设您可以在没有泛型的情况下这样做,这里我有一个名为IShape 的变量x。我可以将什么类型传递给x.Intersect? IShape?这意味着我可以将Circle 传递给它,如果x 在运行时是Rectangle,我不能。

标签: c# generics inheritance methods interface


【解决方案1】:

为了说明我的评论:

interface IShape
{
    bool Intersect(IShape shape);
}

class Circle : IShape
{
    public bool Intersect(IShape shape)
    {
        switch (shape)
        {
            case Circle circle:
                // Circle / circle intersection
                break;

            case Rectangle rectangle:
                // Circle / rectangle intersection
                break;

            ....

            default:
                throw new NotImplementedException();
        }
    }
}

或者使用完全不同的类来处理交叉点,如Eric Lippert's article

【讨论】:

    【解决方案2】:

    您可以像这样使用显式接口实现:

    interface IShape
    {
        bool Intersect(IShape shape);
    }
    
    class Circle : IShape
    {
        bool IShape.Intersect(IShape shape) { return Intersect((Circle)shape); }
        public bool Intersect(Circle shape) { ... }
    }
    

    但是,这会使您的代码非常不安全,因为您可以编写这样的代码并仍然通过编译:

    IShape s = new Circle();
    s.Intersect(new Rectangle());
    

    上面会在运行时抛出异常。

    谨慎使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-22
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      相关资源
      最近更新 更多