使 Point3D 成为从 Point2D 派生并实现 IPoint3D 接口的引用类型的原因

本文关键字:接口 IPoint3D 引用类型 实现 Point3D 派生 Point2D | 更新日期: 2023-09-27 18:30:45

抱歉,如果这对代码审查堆栈交换更好,但我想既然这个问题并不是专门关于代码的,而是关于引用和值类型之间的概念差异,所以这里似乎更好。

搜索给了我一个稍微相关的问题:在 C# 中实现这 3 个类的最佳方法:向量、方向(单位向量)、点——但事实并非如此。另一方面,搜索"参考与值类型"给出的答案过于宽泛。

最近,我开始使用新的 C# 代码库。有很多现有的代码,其中包括以下内容:

public interface IPoint2D
{
    double X { get; set; }
    double Y { get; set; }
}
public interface IPoint3D : IPoint2D
{
    double Z { get; set; }
}
public class Point2D : IPoint2D
{
    public double X { get; set; }
    public double Y { get; set; }
    // ...additional methods ommitted...
}
public class Point3D : Point2D, IPoint3D
{
    public double Z { get; set; }
    // ...additional methods ommitted...
}

如果重要,接口在一个程序集中定义,实现在另一个程序集中定义。

这让我觉得很奇怪,至少原因如下:

  • 像二维或三维坐标这样基本的类型是否需要将其实现隐藏在接口后面?我想它允许使用极坐标或球面坐标实现 Carthesian 接口(例如,您可能RoThetaPoint2D实现 IPoint2D ),但我不记得上一次我想要隐藏在接口后面的坐标系差异是什么时候了。
  • 在我看来,IPoint3D扩展IPoint2D和从Point2D导出Point3D违反了利斯科夫替换原理(尽管我认为在某些射影几何中,人们可能会争辩说3D点"是"2D点)。
  • 使用
  • 引用类型会影响性能,尤其是在使用大型点数组时。
  • System.Tuple<float, float, float>尽管有(
  • 据我所知,甚至BCL设计决策也不是没有争议),但我从未见过将标量三元组视为引用类型的托管代码库。WinForms,WPF,XNA,SharpDX和新的System.Numerics,它们都使用值类型来表示点,矢量,大小,矩形等。

再说一次,在输入这个时,我偶然发现了system.web.ui.datavisualization.charting.point3d,这是一个类(即引用类型)——我想我可以改进更多的例子。

我的问题是;以上述方式对二维和三维点/矢量类型进行编码的充分理由是什么?

因为现在我担心我对现有设计的反应有点下意识,并且完全基于:"我从未见过其他人这样做"和"这会损害性能。这似乎有点弱 - 我很可能忽略了这样做的一些重要原因,我全都听着。

使 Point3D 成为从 Point2D 派生并实现 IPoint3D 接口的引用类型的原因

这是一个固执己见的问题,好吧,这是一个固执己见的答案......

对于如此简单的东西来说,这是太多的抽象和接口。 我只会拥有我需要的不可变向量类型。

即使 Vector3 不断变化,您也在这样做:

ObjectA.Vector3 = SomeTransformationFunction(ObjectA.Vector3);

Vector3在这里完全可以是一个不可变的类型。 我很难找到一种场景,其中描述向量的可变类型更好,因此会说如果有疑问,请尽可能简单。