我正在研究一系列数据结构。有些需要特定数量的维度(如四叉树或八叉树),有些则允许任何数量(例如kd-trees)。我想实现我的不同结构和接口如下:
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接口的要求。我怎么能做到这一点?
修改 我现在按照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
}
答案 0 :(得分:4)
您正在寻找协变返回类型 - 它们在.NET中不存在。您必须使用显式接口实现单独实现这两个属性,以避免它们发生冲突。
一种可能的解决方法是使用通用接口:
public interface IPointEntity<T> where T : IPoint
{
T Location { get; }
}
请注意,还允许类实现IPointEntity<Point>
并避免在访问Point
时将IPoint
装入。{/ p>
答案 1 :(得分:1)
您可以使用通用界面
public interface IPointEntity<T> where T : IPoint
{
T Location { get; }
}
让IPointEntity2D
继承IPointEntity<Point2D>
。