views:

51

answers:

3

I have a class roughly designed as such:

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;
    }
}

I have other classes implementing it as properties, for example:

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

Now to set an entity's position, I use the following:

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

I would like to shorten this up for the user by implementing an array-like initializer for Vector3:

myEntity.Position = { 6, 0, 9 };

However, no class can inherit arrays. Moreover, I know I could somehow manage to get this with minor hacks:

myEntity.Position = new[] { 6, 0, 9 };

But this is not the point here. :)

Thanks!

A: 

There are 2 options:

1) Use object initialization syntax:

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

2) Create a contstructor that takes an array:

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

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

I'm not sure if either are any easier than just

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

Which you already have.

TJB
+1 for object initialization syntax. Additionally, if your `Vector3` is changed from a class to a struct, that syntax will call the default `Vector3` constructor. As a value type, the default constructor can be inlined by the compiler; if you're creating many many many of your `Vector3`s per second, this might help a bit. See: [Shawn Hargreaves Blog: Inline Those Vector Constructors](http://blogs.msdn.com/b/shawnhar/archive/2007/01/02/inline-those-vector-constructors.aspx)
Brian S
Neither of those reduce the amount of code the user has to type.
Lazlo
@Lazlo right, as I said your constructor is probably as short as it gets without some clever hacks.
TJB
+1  A: 

The entire point of the request is to reduce the overall amount of code. It is simply more convenient to do { 1, 2, 3 }. It seems odd that C# does not allow you to overload operators to do this, or allow another way to utilize array initializers for custom reference types.

Tyler Harden
+2  A: 

There is no defined syntax to use array initializer syntax, except for in arrays. As you hint, though, you can add an operator (or two) to your type:

    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");
    }

Then you can use:

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

etc. However, personally I'd just leave it alone, as:

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

which involves less work (no array allocation / initialization, no operator call).

Marc Gravell
I said I could already have this in the question, but this is not what I want. Please read carefully. ^^
Lazlo
@Lazlo - thanks, but I *did* read carefully. That doesn't change the fact that no: without such hacks you can't do it.
Marc Gravell