edA-qa mort-ora-y
edA-qa mort-ora-y

Reputation: 31891

Initialization of const array of struct

How do I do a constant initialization an array of a structure type? For example, in C I would do something like this:

struct Item {
    int a;
    char const * b;
};
Item items[] = {
    { 12, "Hello" },
    { 13, "Bye" },
};

I've been looking at various C# references but can't find an equivalent syntax. Is there one?

Upvotes: 8

Views: 12240

Answers (3)

TByte
TByte

Reputation: 185

Triant's answer is the best in my opinion as it achieves the shortest style with the least amount of code whilst still sticking to struct (not using an intermediate List to achieve the goal which is to have an array). My comment to that answer makes it a tiny bit better in my opinion as it avoids using generics for the tuple and also (as a result), the tuple fields can now be named.

But that answer has given me an idea. What lead me to looking for a very brief style of initializing a struct array is needing to store an array of grouped data in the lightest possible way. So I thought why not use an array of tuples?

(int a, string b)[] items =
{
    (1, "string1"),
    (2, "string2"),
};

This achieves my initial goal, but I admit it's not answering the op's question.

Upvotes: -1

Triant
Triant

Reputation: 41

Another way to do such concise initialization is using implicit conversion operator with a tuple:

struct Item
{
    public int a;
    public string b;

    public Item(int a, string b)
    {
        this.a = a;
        this.b = b;
    }
    public static implicit operator Item(ValueTuple<int, string> tuple)
    {
        return new Item(tuple.Item1, tuple.Item2);
    }
};

Then the initialization can look as simple as this:

Item[] items =
{
    (12, "Hello"),
    (13, "Bye")
};

Please, note the parentheses () instead of curly brackets {}.

This solution doesn't require another class to be defined and doesn't use intermediate List.

Upvotes: 3

Ulugbek Umirov
Ulugbek Umirov

Reputation: 12807

Sample code:

struct Item
{
    public int a;
    public string b;
};
Item[] items = {
    new Item { a = 12, b = "Hello" },
    new Item { a = 13, b = "Bye" }
};

Additional option to introduce parametrized constructor:

struct Item
{
    public int a;
    public string b;

    public Item(int a, string b)
    {
        this.a = a;
        this.b = b;
    }
};
Item[] items = {
    new Item( 12, "Hello" ),
    new Item( 13, "Bye" )
};

As @YoYo suggested, removed new[] part.

Tricky way (for the case where new Item bothers you much)

Declare new class:

class Items : List<Item>
{
    public void Add(int a, string b)
    {
        Add(new Item(a, b));
    }
}

Then you can initialize it as:

Items items = new Items {
    { 12, "Hello" },
    { 13, "Bye" }
};

You can also apply .ToArray method of List to get an array of Items.

Item[] items = new Items {
    { 12, "Hello" },
    { 13, "Bye" }
}.ToArray();

The trick is based on collection initializers (http://msdn.microsoft.com/en-us/library/bb384062.aspx):

By using a collection initializer you do not have to specify multiple calls to the Add method of the class in your source code; the compiler adds the calls.

Upvotes: 13

Related Questions