我正在研究一系列数据结构。有些需要特定数量的维度(例如四叉树或八叉树),有些则允许任意数量(例如 kd 树)。我想实现不同的结构和接口(interface),如下所示:
public struct Point : IPoint // An n-dimensional point
public struct Point2D : IPoint // A 2-dimensional point
public interface IPointEntity
{
IPoint Location { get; }
}
public interface IPointEntity2D : IPointEntity
{
Point2D Location { get; }
}
这样,我就可以创建这样的类:
public class Quadtree
{
public void Add(IPointEntity2D value) {...}
}
public class KdTree
{
public void Add(IPointEntity value) {...}
}
但是,我被告知 IPointEntity2D
必须将 Location
声明为 New
,因为它隐藏了 IPointEntity.Location
。但这违背了目的,因为我必须分别实现它们。在我看来,2D 实现应该满足 n-D 接口(interface)的要求。我怎样才能做到这一点?
编辑: 我现在已经按照 Jon Skeet 的建议实现了它:
public struct Point : IPoint // An n-dimensional point
public struct Point2D : IPoint // A 2-dimensional point
public interface IPointEntity<T> where T : IPoint
{
T Location { get; }
}
public class Quadtree<T> where T : IPointEntity<Point2D>
{
public void Add(T value) {...}
}
public class KdTree<T> where T : IPointEntity<IPoint>
{
public void Add(T value) {...}
}
但是当我尝试创建一个实体时,我无法像我希望的那样在两个适当的类中使用它们:
public class Sprite2D : IPointEntity<Point2D>
{
public Point2D Location { get; set; }
}
public class Sprite3D : IPointEntity<Point3D>
{
public Point3D Location { get; set; }
}
static void Main(string[] args)
{
var quadtree = new Quadtree<Sprite2D>(); // Works just great
var kdTree2D = new KdTree<Sprite2D>(); // Doesn't work
var kdTree3D = new KdTree<Sprite3D>(); // Doesn't work
}
最佳答案
您正在寻找协变返回类型 - 它们在 .NET 中不存在。您必须分别实现这两个属性,使用显式接口(interface)实现来避免它们发生冲突。
一种可能的解决方法是使用通用接口(interface):
public interface IPointEntity<T> where T : IPoint
{
T Location { get; }
}
请注意,这还允许类实现 IPointEntity<Point>
并避免拳击 Point
进入IPoint
当它被访问时。
关于c# - 接口(interface)如何实现逐渐更严格的类型化属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5800322/