gpt4 book ai didi

c# - 运算符重载放置和冗余

转载 作者:行者123 更新时间:2023-11-30 17:47:26 25 4
gpt4 key购买 nike

我有多个结构如下:Vector2、Vector3、Vector4。每个结构都有为基本算术运算以及隐式和显式转换定义的运算符重载。

到目前为止,我已经在 Vector4 类中添加了所有可能的组合:

public static Vector4 operator + (Vector4 v1, Vector4 v2) { return (new Vector4(...)); }
public static Vector4 operator + (Vector4 v1, Vector3 v2) { return (new Vector4(...)); }
public static Vector4 operator + (Vector3 v1, Vector4 v2) { return (new Vector4(...)); }

public static implicit operator Vector4 (Vector2 v) { return (new Vector4(v)); }
public static implicit operator Vector4 (Vector3 v) { return (new Vector4(v)); }

public static explicit operator Vector3 (Vector4 v) { return (new Vector3(v)); }
public static explicit operator Vector2 (Vector4 v) { return (new Vector2(v)); }

是否有关于哪些运算符更适合哪种结构的指南?我无法想象任何一种方式都会损害性能,但我很想知道如果其他开发人员遇到这段代码,他们会更直观地了解什么。运算符组合的数量迅速增加到几十种。

顺便说一句,在其他类中复制这些运算符不会导致编译时错误。我没有检查将调用哪个实现,但这不是重点。

最佳答案

如果每个类代表二维、三维和四维向量,我认为您应该可以减少一些代码。这是因为只要您具有必要的隐式上转换,不同维度的向量之间的向量算术定义 就是多余的。因此不需要像下面这样的运算符:

public static Vector4 operator + (Vector4 v1, Vector3 v2) { return (new Vector4(...)); }
public static Vector4 operator + (Vector3 v1, Vector4 v2) { return (new Vector4(...)); }

我还建议让低维向量处理高维向量的上转换和下转换。那是因为下转换剥离了信息,如何做的选择应该在“更有限”的结构中。

因此,VectorI 结构将需要对所有 VectorI+J 的隐式上转换和对所有 VectorI-J 结构的显式下转换.此外,VectorI 结构需要实现自己的向量算法。但由于“I”只有值 2、3 和 4,这意味着:

  1. Vector2 需要隐式转换为 Vector3 和 Vector4,以及从 Vector3 和 Vector4 显式向下转换。

  2. Vector3 需要隐式转换为 Vector4 以及从 Vector4 显式向下转换。

  3. Vector4 不需要转换。

  4. 所有 4 个结构都为它们自己实现线性代数方法,仅在相同维度的向量之间。

我刚刚测试了这个方案并添加了不同的 Vector2、Vector3 和 Vector4 结构,在完成隐式转换的情况下按预期工作。

更新

刚刚做了一个加法的快速原型(prototype)实现,所有的跨维度加法都按预期工作:

public struct Vector2
{
public double x, y;

public Vector2(double x, double y)
{
this.x = x; this.y = y;
}

#region linear algebra

public static Vector2 operator +(Vector2 first, Vector2 second)
{
return new Vector2(first.x + second.x, first.y + second.y);
}

#endregion

#region conversions to/from higher dimensions

public static implicit operator Vector3(Vector2 v2)
{
return new Vector3(v2.x, v2.y, 0);
}

public static implicit operator Vector4(Vector2 v2)
{
return new Vector4(v2.x, v2.y, 0, 0);
}

public static explicit operator Vector2(Vector3 v3)
{
return new Vector2(v3.x, v3.y);
}

public static explicit operator Vector2(Vector4 v4)
{
return new Vector2(v4.x, v4.y);
}

#endregion
}

public struct Vector3
{
public double x, y, z;

public Vector3(double x, double y, double z)
{
this.x = x; this.y = y; this.z = z;
}

#region linear algebra

public static Vector3 operator +(Vector3 first, Vector3 second)
{
return new Vector3(first.x + second.x, first.y + second.y, first.z + second.z);
}

#endregion

#region conversions to/from higher dimensions

public static implicit operator Vector4(Vector3 v3)
{
return new Vector4(v3.x, v3.y, v3.z, 0);
}

public static explicit operator Vector3(Vector4 v4)
{
return new Vector3(v4.x, v4.y, v4.z);
}

#endregion
}

public struct Vector4
{
public double x, y, z, w;

public Vector4(double x, double y, double z, double w)
{
this.x = x; this.y = y; this.z = z; this.w = w;
}

#region linear algebra

public static Vector4 operator +(Vector4 first, Vector4 second)
{
return new Vector4(first.x + second.x, first.y + second.y, first.z + second.z, first.w + second.w);
}

#endregion
}

下面的测试代码可以正常工作:

public static class VectorHelper
{
public static void Test()
{
var v2 = new Vector2(5, 5);
var v3 = new Vector3(7, 7, 7);
var v4 = new Vector4(3, 3, 3, 3);

var res1 = v2 + v3;
Debug.Assert(res1.GetType().Name == "Vector3"); // No assert
var res2 = v3 + v4;
Debug.Assert(res2.GetType().Name == "Vector4"); // No assert
var res3 = v2 + v4;
Debug.Assert(res3.GetType().Name == "Vector4"); // No assert
Debug.Assert(res3.x == 8 && res3.y == 8 && res3.z == 3 && res3.w == 3); // No assert
}
}

关于c# - 运算符重载放置和冗余,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24793705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com