1

Is it possible to create custom collection, that would have initializing syntax like 2dim arrays, for example:

var matrix = new Matrix(){{1,1},{2,2}};

EDIT

I understand that it seems to looke like a very common question, but indexers is not a problem, problem is initializing syntax. This is my little whim. So, is it possible to get EXACTLY the same expression? The most simmilar I obtain is:

var matrix = new Matrix() { new List<int>() {1, 2} };
RusBes
  • 55
  • 7
  • 3
    yes it's possible to create a class.. do a google search on the following and you will see tons of examples .`C# Stackoverflow alternative to 2 dimensional array` perhaps `List of List` which would look like this for example `List>` – MethodMan Dec 10 '17 at 00:36
  • 1
    Possible duplicate of [Alternate to 2D array in C#](https://stackoverflow.com/questions/36014086/alternate-to-2d-array-in-c-sharp) – Camilo Terevinto Dec 10 '17 at 00:37
  • What should this matrix be able to do that 2d array can't? – Olivier Jacot-Descombes Dec 10 '17 at 00:50
  • It should looks like arrays but be able to do much more things. It doesn't matter, I edit question and describe my problem – RusBes Dec 10 '17 at 01:13

5 Answers5

4

To achieve the implementation of the initialization syntax you can use collection initializers on your object but only if that object implements IEnumerable.

If the object implements IEnumerable then you can add an Add method that will be called when you initialize an object. As an example here is how you might initizlize entries in a simple matrix class:

public class Matrix : IEnumerable
{
    public int[,] _data = new int[3,3];

    public void Add(int x, int y, int value)
    {
        _data[x,y] = value;
    }
    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }    
}

I can initialize it like this:

var myObject = new Matrix() {
    {1,2,3}, 
    {0,0,10}
};

This will be the equivalent of writing:

var myObject = new Matrix();
myObject.Add(1,2,3);
myObject.Add(0,0,10);

Custom Collection Initializers is a question about custom collection initializers which, amongst other things, has a quote from the spec about them.

As mentioned earlier this only works for objects that implement IEnumerable. As demonstrated above you don't have to have a useful implementation of IEnumerable for this to work but I would discourage you from making something IEnumerable to get this behaviour if the object isn't really an IEnumerable.

Chris
  • 27,210
  • 6
  • 71
  • 92
2
public int this[int index1, int index2] { 
    // This is the get accessor. 
    get { 
        return index1 + index2;
    }
}

Source: http://www.java2s.com/Tutorial/CSharp/0140__Class/Atwodimensionalindexer.htm

Pyotreq
  • 146
  • 1
  • 1
  • 6
  • 1
    I have NO clue who upvotes this. You are simply returning the sum of the indices - that is NOT what an indexer is about. It is about accessing an internal data structure and (maybe) changing the kind of indexing used from 2dim to 1dim or whatever.... – Patrick Artner Dec 10 '17 at 01:01
  • 1
    @PatrickArtner: It shows the syntax of a two dimensional indexer. The actual body isn't very useful but the answerer presumably thought that how to writre the indexer was the questioner's problem, not the content of that indexer. – Chris Dec 10 '17 at 01:04
  • Indexers is not a problem) i only want to reach a certain initializing syntax (and all other syntax which applies to arrays) – RusBes Dec 10 '17 at 01:07
1

If you want it to use the array initialize syntax just add an Add method and implement IEnumerable.

 public void Add(int a, int b) { ... }
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
0

You can emulate it, f.e. with an internal List:

To make it safe(ish) you would need to add lots of checks, to make it work via your Initializerlist you could provide and IEnumerable constructor and pass it into that.

AFAIK there is not a way to make your wish of "autodeconstructing" a Matrix true.

    // main method - declares a matrix, fills one value, prints all
    static void Main()
    {
        Mat m = new Mat(8, 8);
        m[4, 2] = 55;

        Console.WriteLine(m);
        Console.ReadLine();
    }

    private class Mat
    {
        public Mat(int mRow, int mCol)
        {
            maxCol = mCol;
            maxRow = mRow;
            // prefill data with 0 - could use default
            data = new List<int>(Enumerable.Range(0, mCol * mRow).Select(n => 0)); 
        }

        // https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/
        public int this[int row, int col]
        {
            get
            {
                return data[row * maxCol + col];
            }
            set { data[row * maxCol + col] = value; }
        }

        // lenghty to string method 
        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append("[ ");
            for (int r = 0; r < maxRow; r++)
            {
                sb.Append("[ ");

                for (int c = 0; c < maxCol; c++)
                {
                    sb.Append(this[r, c]);
                    if (c < maxCol - 1)
                        sb.Append(", ");
                }
                sb.Append(" ]\n");
                if (r < maxRow - 1)
                    sb.Append(", ");
            }
            sb.Append(" ]\n");
            return sb.ToString();
        }

        private int maxCol;
        private int maxRow;
        private List<int> data { get; set; }
    }
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
0
class Matrix : IEnumerable
{
    List<int[]> rowList = new List<int[]>();

    public void Add(params int[] row)
    {
        rowList.Add(row);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return rowList.GetEnumerator();
    }
}
skyoxZ
  • 362
  • 1
  • 3
  • 10