c# - 如何从接口(interface)返回派生程度更高的类型?

标签 c# generics interface covariance

我有一个接口(interface)可以转换我想要实现的数据网格:

public interface ITransformable<T>
{
    T Slice(int x, int y, int width, int height);
    T Slice(Rectangle value);
    T Transpose();
    T Flip(bool horizontal, bool vertical);
    T Rotate(bool clockwise);
}

所以我创建了一个类:

public class Mesh<T> : ITransformable<Mesh<T>>
{
    public Mesh<T> Transpose() { ... }
    /// etc
}

但是,在制作更衍生版本的网格时,我遇到了一个问题。例如,我有一个 Heightmap类是 Mesh<float> .通过 T 的特定实现,这允许我使用运算符重载,这样我就可以轻松地将两个高度图添加在一起,例如。但是当我实现它时

public class Heightmap : Mesh<float> { ... }

Heightmap来自 ITransformable 的函数仍然返回网格,而不是高度图。有什么方法可以在 Mesh 中实现基本行为吗? ,但是“更改”更多派生类中的返回类型?我认为这是协变的目的,但我似乎无法弄清楚。

最佳答案

请尝试下面的代码,它应该像 charm 一样工作。将方法/异常替换为您自己的实现。

  public interface ITransformable<T, out S> where S : ITransformable<T, S>
    {
        S Slice(int x, int y, int width, int height);
        S Slice(Rectangle value);
        S Transpose();
        S Flip(bool horizontal, bool vertical);
        S Rotate(bool clockwise);
    }

    public class Mesh<T, S> : ITransformable<T, S> where S : Mesh<T,S>, ITransformable<T, S>, new()
    {
        public S Slice(int x, int y, int width, int height)
        {
            throw new NotImplementedException();
        }

        public S Slice(Rectangle value)
        {
            throw new NotImplementedException();
        }

        public S Transpose()
        {
           //The following will work smoothly.
           S sObject = this.Slice(10, 20, 30, 40);
           return sObject;
        }
        public S Flip(bool horizontal, bool vertical)
        {
            throw new NotImplementedException();
        }

        public S Rotate(bool clockwise)
        {
            throw new NotImplementedException();
        }

    }

    public class Heightmap : Mesh<float, Heightmap>
    {

    }

    public class Program
    {
        static void Main()
        {
            Heightmap heightmap = new Heightmap();
            Heightmap map2 = heightmap.Transpose(); //This will work smoothly.
        }
    }

关于c# - 如何从接口(interface)返回派生程度更高的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24442267/

相关文章:

c# - 无法创建静态类的实例 'Random'

c# - 如何使用 XmlSerializer 和 Autofac 注入(inject)依赖项?

c# - 不必要地转换为用于在 mscorlib 中调用 ToString() 的对象

c# - 强制 C# 转换为泛型

c# - 如何手动滚动面板?

c# - 如何在泛型方法中比较两个值?

generics - 带有泛型的 SAM 转换

c# - 暴露泛型重载的接口(interface)。如何在这里干燥?

c# - Web 服务无法序列化接口(interface)

java - 在 RMI 中将子类对象转换为父类(super class)引用