如果这对 Code Review 堆栈交换更好,我深表歉意,但我想因为这个问题并不是真正与代码有关,而是更多关于引用类型和值类型之间的概念差异,所以这里似乎更好。
搜索给了我这个稍微相关的问题:Best Way of Implementing these 3 classes in C#: Vector, Direction (unit vector), Point ——但还不完全是。另一方面,搜索“引用类型与值类型”给出的答案过于宽泛。
最近我开始在新的 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...
}
万一重要,接口(interface)在一个程序集中定义,实现在另一个程序集中定义。
这让我觉得很奇怪,至少有以下原因:
- 像 2 维或 3 维坐标这样基本的类型是否需要将其实现隐藏在接口(interface)之后?我想它允许使用极坐标或球坐标实现 Carthesian 接口(interface)(例如,您可以使用
RoThetaPoint2D
实现IPoint2D
),但我不记得上次我想在接口(interface)后面隐藏这样的坐标系差异是什么时候了。 - 在我看来
IPoint3D
扩展IPoint2D
和Point3D
源自Point2D
违反了 Liskov substitution principle (尽管我认为在某些射影几何中,人们可能会争辩说 3D 点"is"2D 点)。 - 使用引用类型会影响性能,尤其是在使用大型点数组时。
-
System.Tuple<float, float, float>
尽管如此(据我所知,甚至 BCL 设计决策也并非没有争议),我从未见过将标量三元组视为引用类型的托管代码库。 WinForms、WPF、XNA、SharpDX,以及新的System.Numerics,它们都使用值类型来表示Point、Vector、Size、Rect等。
再一次,当我输入这个时,我偶然发现了 system.web.ui.datavisualization.charting.point3d
,这是一个类(即引用类型)——我想我可以举出更多的例子。
我的问题是; 按上述方式对 2 维和 3 维点/矢量类型进行编码的充分理由是什么?
因为现在我担心我对现有设计的 react 有点下意识,并且完全基于:“我从未见过其他人那样做。”和“这会影响性能。”。这似乎有点弱——我很可能会忽略一些以这种方式做事的重要原因,我洗耳恭听。
最佳答案
这是一个自以为是的问题,好吧,这是一个自以为是的答案......
对于如此简单的东西来说,抽象和接口(interface)太多了。我会简单地拥有我需要的不可变向量类型。
即使 Vector3 不断变化,你也是这样做的:
ObjectA.Vector3 = SomeTransformationFunction(ObjectA.Vector3);
Vector3 在这里完全可以是不可变类型。我很难找到一种场景,其中描述向量的可变类型更好,因此我会说,如果有疑问,请尽可能简单。
关于c# - 使 Point3D 成为从 Point2D 派生并实现 IPoint3D 接口(interface)的引用类型的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26999295/