如何在自定义向量类中使用数组初始化语法?

4

我有一个类,大致设计如下:

class Vector3
{
    float X;
    float Y;
    float Z;

    public Vector3(float x, float y, float z)
    {
        this.X = x;
        this.Y = y;
        this.Z = z;
    }
}

我有其他类将其实现为属性,例如:

class Entity
{
    Vector3 Position { get; set; }
}

现在我使用以下代码设置实体的位置:

myEntity.Position = new Vector3(6, 0, 9);

我想通过为 Vector3 实现类似数组的初始化器来简化用户的操作:
myEntity.Position = { 6, 0, 9 };

然而,没有任何类可以继承数组。此外,我知道我可以通过一些小技巧来解决这个问题:
myEntity.Position = new[] { 6, 0, 9 };

但这不是重点。:)
谢谢!
3个回答

3

在除数组之外,没有定义使用数组初始化器语法的语法。不过,正如您所示,您可以向您的类型添加一个或两个运算符:

    public static implicit operator Vector3(int[] value)
    {
        if (value == null) return null;
        if (value.Length == 3) return new Vector3(value[0], value[1], value[2]);
        throw new System.ArgumentException("value");
    }
    public static implicit operator Vector3(float[] value)
    {
        if (value == null) return null;
        if (value.Length == 3) return new Vector3(value[0], value[1], value[2]);
        throw new System.ArgumentException("value");
    }

那么您可以使用以下代码:

obj.Position = new[] {1,2,3};

等等。然而,个人认为最好别管它,因为:

obj.Position = new Vector3(1,2,3);

这涉及到更少的工作(没有数组分配/初始化,没有操作符调用)。


我说过我在问题中已经可以做到这一点,但这不是我想要的。请仔细阅读。^^ - Lazlo
@Lazlo - 谢谢,但我确实仔细阅读了。这并不能改变没有这种技巧的事实:你无法做到。 - Marc Gravell

1
整个请求的目的是为了减少代码总量。用 {1, 2, 3} 更方便简洁。看起来奇怪的是C#不允许你重载运算符来实现这一点,或者允许另一种方式来利用数组初始化器来定义自定义引用类型。

0

有两个选项:

1)使用对象初始化语法:

myEntity.Position = new Vector3(){ X = 6, Y = 0, Z = 9 };

2) 创建一个接受数组的构造函数:

Vector3( float[] array )
{
  // Validate, set X = array[0] etc.
}

myEntity.Position = new Vector3( new float[3]{ 6, 0, 9} );

我不确定哪个比起只是

myEntity.Position = new Vector3( 6, 0, 9 );

你已经拥有了。


+1 对象初始化语法。此外,如果你的 Vector3 从类更改为结构体,则该语法将调用默认的 Vector3 构造函数。作为值类型,编译器可以内联默认构造函数;如果你每秒创建很多 Vector3,这可能会有所帮助。参见:Shawn Hargreaves 的博客:内联那些向量构造函数 - Brian S
这两种方法都不能减少用户需要输入的代码量。 - Lazlo
@Lazlo 对,就像我说的,你的构造函数可能已经尽可能简短了,除非使用一些巧妙的技巧。 - TJB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接