2

I have a class called Matrix : IEnumerable<double>, (classic, mathematical matrix. It is basically a 2D array with some goodies).

The class is immutable, so there is no way to change its values after instance creation.

If want to create a matrix with pre-existing values I have to pass an array to the constructor like this:

double[,] arr = new double[,]
{
    {1,2,3}, {4,5,6}, {7,8,9}
};
Matrix m = new Matrix(arr);

Is there a way to turn it into this: (?)

Matrix m = new Matrix
{
    {1,2,3}, {4,5,6}, {7,8,9}
};

Update:

Found a hack-ish way yo make it work. I'm not sure if this solution is advisable, but it works.

class Matrix : ICloneable, IEnumerable<double>
{
        // Height & Width are initialized in a constructor beforehand.
        /*
         * Usage:
         * var mat = new Matrix(3, 4)
         * {
         *              {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}
         * };
         */
        int rowIndex;
        bool allowArrayInitializer;
        double[,] tempData;
        double[,] data;
        public void Add(params double[] args)
        {
                if(!allowArrayInitializer)
                        throw new InvalidOperationException("Cannot use array initializer");
                if(args.Length != Width || rowIndex >= Height)
                        throw new InvalidOperationException("Invalid array initializer.");
                for(int i = 0; i < Width; i++)
                        tempData[i, rowIndex] = args[i];
                if(++rowIndex == Height)
                        data = tempData;
        }
}
2
  • 3
    Of course you can do Matrix m = new Matrix(new double[,]{{1,2,3}, {4,5,6}, {7,8,9}}); Commented Jul 7, 2013 at 16:13
  • @dasblinkenlight Not what I was aiming for :) Commented Jul 7, 2013 at 16:42

3 Answers 3

5

Not if it’s immutable; that syntactic sugar is implemented using Add().

Sign up to request clarification or add additional context in comments.

10 Comments

With an interface? Would be nice to know, sometimes this is useful.
Does the Add() method have to be public? I could live with it being mutable-if-you-don't-want-to-use-reflection.
@FelixK.: I’m not sure, but I don’t think so. msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx is all I’ve found so far…
@GiladNaaman: No, it’s not how vanilla arrays are implemented; arrays are a… more special feature of the language. They’ve also been around for much longer.
|
0

You will not able to do it via initializer but should be able to do it via parameterized constructor. You can see the sample code below :

class Matrix : IEnumerable<double>
{
    double[,] input;
    public Matrix(double[,] inputArray)
    {
        input = inputArray;
    }

    public IEnumerator<double> GetEnumerator()
    {
        return (IEnumerator<double>)input.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return input.GetEnumerator();
    }
}

In the main method :

    static void Main(string[] args)
    {
        var m = new Matrix(new double[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } });
    }

I hope this helps you!

3 Comments

I don't see how it differs from the example I gave in the original post.
This is… what the question wanted to avoid?
@Gilad Naaman, I took around 15 mins to type, test and post. After posting I realized you have given the BEST answer !!!. Please do not simply reduce the points!
0

instead of deriving from IEnumerable I would use a property:

class Matrix 
{
        public double[,] Arr { get; set; }
}

Matrix m = new Matrix
{
      Arr = new double [,] { {1d,2d,3d}, { 4d,5d, 6d}}
};

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.