我希望所有运算符都被覆盖一次,因为它们完全相同.在C++中我可以定义类Vector {float x,y,z; },并且做typedef Point = Vector,typedef Direction = Vector; 在C#中没有等价物("使用Point = Vector;"很糟糕,因为你必须将它放在你使用的每一个文档中,并且它不是由编译器强制执行的).
我试图定义3个不同的类并覆盖每个类的运算符,然后执行隐式类型转换,这会使代码运行得更慢等等.
我尝试定义只是Vector,然后点:向量和方向:向量,这种方式我只编写一次运算符但我不能做隐式类型转换Point < - > Vector或Direction < - > Vector.
我可以简单地定义Vector类并在任何地方使用它,但这会产生模糊性,因为天气变量应该是空间中的位置(Point),空间中的相对位置(Vector)或单位矢量(Direction).例如功能:
Vector GetOrthogon(Vector a, Vector b) {
// ....
}
Run Code Online (Sandbox Code Playgroud)
你无法知道它是否期望任何向量或单位向量.在C++中你可以这样做,为什么不在C#?
注意:如果可能的话,使用结构而不是类是理想的.
Nat*_*Nat 11
数学上,点是矢量.太空中没有绝对点.点被定义为来自某个任意来源的向量.所以,我使用矢量来获得点和点之间的差异.
因为方向是单位向量,所以也不需要区分.这就像尝试为整数1和其他整数定义不同的静态类型.所以我使用矢量用于两个方向和点之间的差异.
因此,定义一个Vector类型.它会让你的生活更轻松,因为你会有更少的类和重载的操作符/函数来编写和测试,并且在数学上会更"纯粹"(如果这对你很重要).
在一个纯粹的水平,我要说的却是一个Vector和Point是不一样的,通过代数:
Point+ Vector=> Point(翻译)Vector+ Vector=> Vector(另外)Point+ Point(未定义)我将有2个隐式(它们在逻辑上等价)或显式(否则)转换运算符的不可变结构.我可能不会有一个Direction结构,但是......我可能有一个Direction属性可以将Vector它扩展到单位,但这就是它...
我已经删除了一个原语Vector并Point显示了相互作用; 我没有填写所有Point(因为它更简单):
public struct Point {
public Point(double x, double y) : this() { X = x; Y = y; }
public double X { get; private set; }
public double Y { get; private set; }
// and more ;-p
}
public struct Vector : IEquatable<Vector> {
public Vector(double x, double y) : this() { X = x; Y = y; }
public Vector AsUnit() {
if (X == 0 && Y == 0) throw new InvalidOperationException();
if (X == 0) return new Vector(0, X > 0 ? 1 : -1);
if (Y == 0) return new Vector(Y > 0 ? 1 : -1, 0);
double sqr = Math.Sqrt((X * X) + (Y * Y));
return new Vector(X / sqr, Y / sqr);
}
public double X { get; private set; }
public double Y { get; private set; }
public static explicit operator Point(Vector vector) {
return new Point(vector.X, vector.Y);
}
public static explicit operator Vector(Point point) {
return new Vector(point.X, point.Y);
}
public override string ToString() {
return "(" + X.ToString() + "," + Y.ToString() + ")";
}
public override int GetHashCode() {
return 17 * X.GetHashCode() + Y.GetHashCode();
}
public override bool Equals(object obj) {
return obj == null ? false : Equals((Vector)obj);
}
public bool Equals(Vector vector) {
return X == vector.X && Y == vector.Y;
}
public static bool operator ==(Vector a, Vector b) {
return a.X == b.X && a.Y == b.Y;
}
public static bool operator !=(Vector a, Vector b) {
return a.X != b.X || a.Y != b.Y;
}
public static Point operator +(Point point, Vector vector) {
return new Point(point.X + vector.X, point.Y + vector.Y);
}
public static Point operator -(Point point, Vector vector) {
return new Point(point.X - vector.X, point.Y - vector.Y);
}
public static Vector operator +(Vector a, Vector b) {
return new Vector(a.X + b.X, a.Y + b.Y);
}
public static Vector operator -(Vector a, Vector b) {
return new Vector(a.X - b.X, a.Y - b.Y);
}
}
Run Code Online (Sandbox Code Playgroud)
已经有Point和Vector在.net> = 3.0的实施方式.不幸的是,System.Windows.Media.Media3D因为它们是WPF 3D API的一部分.
这些现有的类确实有一些有用的属性,值得研究(其他人已经提到过):
Point [+|-] Vector = PointVector [+|-] Vector = VectorPoint - Point = VectorVector 有静态方法来执行点和交叉产品Vector.Normalise()并vector.Negate()做他们在锡上说的话也许您可以检查(甚至扩展)这些以供您自己使用?