0

I have a 3D array that I'm accessing this way Array(int x, int y, int z). What I would like to know, if it is possible to have a struct, that has xyz in it, so that I can use it this way: Array(struct xyz). If it is, then how?

The reason for why I would want this, is that it would be easier for me to read and write, and that it would be alot simpler and less error prone to write. Makes it easier to maintain the bigger picture.

I do know that I could make a class that has its own method, but since I have many classes and applying it to each one would make me quickly loose the readability, using the struct directly would be a better option if available.

Example:

public struct xyz
{
    public int x, y, z;

    public xyz(int X, int Y, int Z)
    {
        x = X;
        y = Y;
        z = Z;
    }
}

private void Test()
{
    int(,,) Array = new int()
    {
        {
            {0,0},
            {0,0},
        },
        {
            {0,0},
            {0,0},
        }
    };
    xyz XYZ = new xyz(0,0,0);
    Array[XYZ] = 1; // this instead of
    Array[XYZ.x, XYZ.y, XYZ.z] = 1 // this
}
4
  • 1
    Why have you reversed all of the guidelines for c# casing? It's distracting... Commented Feb 15, 2012 at 1:31
  • Can you? No you can't, that's not the way arrays work. You could create extension methods however that accepts them and use those. Commented Feb 15, 2012 at 1:31
  • And why are you using VB indexing syntax when the question is tagged C#? Commented Feb 15, 2012 at 3:42
  • Do you mean that I used the () instead of the []? If so, then its because I had trouble posting the question, so I tried to test if the [] was responsible, turned out that I had to make 4 spaces infront of the code... I am using Microsoft Visual C# 2010 Express. Commented Feb 15, 2012 at 8:07

3 Answers 3

1

You could create your own array class that wraps a real array, and provides an indexer to do what you want:

class MyArray<T>
{
    private T[,,] array;

    public MyArray(int xSize, int ySize, int zSize)
    {
        array = new T[xSize,ySize,zSize];
    }

    public T this[XYZ xyz]
    {
        get { return array[xyz.x, xyz.y, xyz.z]; }
        set { array[xyz.x, xyz.y, xyz.z] = value; }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you didn't realize it until svick shined some light on my question. Didn't know that they would be treated like variables. Thanks for your answer, although, one thing would make me realize it, would be an example, but I am a rookie in programming.
1

You can easily achieve that by creating your own collection that can be accessed either by specifying all thee coordinates separately:

public T this[int x, int y, int z] { get { … } set { … } }

Or by your XYZ struct:

public T this[XYZ xyz]  { get { … } set { … } }

You can't add that indexer to array, extension indexers are not possible. What you could do is to create two extension methods. Something like:

public static T Get<T>(this T[,,] array, XYZ xyz)
{
    return array[xyz.X, xyz.Y, xyz.Z];
}

public static void Set<T>(this T[,,] array, XYZ xyz, T value)
{
    array[xyz.X, xyz.Y, xyz.Z] = value;
}

And then use it like this:

int i = array.Get(xyz);
array.Set(xyz, 25);

Also, creating mutable structs, like you did, is considered worst practice in C#. They can be very confusing.

5 Comments

Mutable structs are not necessarily bad. There is nothing wrong with simple POD objects. Now if you were trying to use structs in place of classes where they do more than just hold data but manipulates it and whatnot, then yes it's bad.
I have one question about the public T this[XYZ xyz] { get{ ... } set { ... } } Don't know how to reference the Array. What do I write inside the get and set?
@Eli, look at Andrew Cooper's answer.
@JeffMercado: I wish more people would realize that when value semantics are desired, POD structs with exposed fields are in almost every way better than structs which only expose readonly properties, and only allow fields to be set in the "constructor". There are many cases where it makes sense for struct instances to be immutable, but if one is using a compiler which properly forbids mutating the fields of a readonly struct, only time it really makes sense to restrict access to fields is when a struct is supposed to guarantee a relationship between them, e.g.
@JeffMercado: ... a PreHashed<T> struct with fields T Value; int HashCode, whose constructor sets HashCode to Value.GetHashCode(). Forbidding code from writing Value or HashCode except in the constructor, which writes both, would help minimize the likelihood of code reading a HashCode which does not match Value.
0

Completing the solution of @Andrew Cooper, if you also want to access that matrix normally you must add this methods (Look at the end of Andrew's code)

class MyArray<T>
{
    private T[,,] array;

    // Constructor
    public MyArray(int xSize, int ySize, int zSize)
    {
        array = new T[xSize,ySize,zSize];
    }

    // Index with your own struct XYZ
    public T this[XYZ xyz]
    {
        get { return array[xyz.x, xyz.y, xyz.z]; }
        set { array[xyz.x, xyz.y, xyz.z] = value; }
    }

    // Normal index
    public T this[int x, int y , int z]
    {
        get { return array[x, y, z]; }
        set { array[x, y, z] = value; }
    }

    // Get dimensions
    public int GetLength(int dim)
    {
        return array.GetLength(dim);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.