-1

I keep getting:

Array initializers can only be used in a variable or field initializer. Try using a new expression instead.

I have no idea why. Is this not possible with C#. A similar construct works with simple types such as int or float.

public struct UnitObject 
{
    public float    v;
    public string   t;
    public string   d;
}

public class UnitStandard
{
    public UnitObject[] UnitDict = new UnitObject[] { { 1f, "s", "s" } };
} 

Using .NET 4.5.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
cdcdcd
  • 547
  • 1
  • 5
  • 15
  • 1
    How's `{ 1f, "s", "s" }` supposed to be converted to a `UnitObject`? – Camilo Terevinto Nov 19 '17 at 21:08
  • As in the same way you define an initialiser for an array of type int. A structure is just a new type with three implicit fields. – cdcdcd Nov 19 '17 at 21:10
  • I don't think that `anonymous types == structs`. – Ian H. Nov 19 '17 at 21:20
  • Sorry Chaps my last point should have been.As in the same way you define an initialiser for an array of type int. A structure is just a new type with three implicit fields. Do I need a constructor for the structure. I'm sorry but I'm coming from a C background and I've been at this for nearly an hour now. – cdcdcd Nov 19 '17 at 21:21
  • Additionally, mutable structs are usually [a bad idea](https://stackoverflow.com/questions/441309/why-are-mutable-structs-evil) in C#. You should make the struct immutable or use a `class` instead. – Blorgbeard Nov 19 '17 at 21:34
  • Thanks Blorgbeard - will do that. Thanks. – cdcdcd Nov 19 '17 at 21:44

2 Answers2

3

It's not completely clear how you expect that to work, but in c#, it's not valid syntax. You have two options:

  1. Use a constructor

    public struct UnitObject
    {
        public UnitObject(float v, string t, string d)
        {
            this.v = v;
            this.t = t;
            this.d = d;
        }
    }
    
    public UnitObject[] UnitDict = new UnitObject[] { new UnitObject(1, "s", "s") };
    
  2. Use the object initializer

    public UnitObject[] UnitDict = new UnitObject[] 
    { 
        new UnitObject 
        { 
            v = 1, 
            t = "s", 
            d = "s" 
        } 
    };
    

As a side note: v, t and d are horrible names because they do not provide meaning and public members should follow PascalCase.

In order to follow the correct immutability pattern, use this:

public struct UnitObject
{
    public float V { get; private set; }
    public string T { get; private set; }
    public string D { get; private set; }

    public UnitObject(float v, string t, string d)
    {
        V = v;
        T = t;
        D = d;
    }
}
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
  • Cheers Camilo your last comment really helped. I tried a constructor after another search on the web. After hacking around a bit I got a solution - but yours is the better implementation. The names are just for experimentation. Thanks. – cdcdcd Nov 19 '17 at 21:43
  • @cdcdcd Glad that it helped. I made an edit to reflect what Blorgbeard commented – Camilo Terevinto Nov 19 '17 at 21:47
1

I'm answering my own question here as I was advised this was the best way to help others - rather than editing the question.

I got this to work by adding a constructor:

public struct UnitObject 
{
    public float    v;
    public string   t;
    public string   d;

    public UnitObject(float val, string s1, string s2)
    {
       v = val; t = s1; d = s2;
     }
}

public class UnitStandard
{
    public UnitObject[] UnitDict = new UnitObject[] { new UnitObject( 1f, "s", "s" ) };
} 

But Camilo's answer is much more elegant of course.

cdcdcd
  • 547
  • 1
  • 5
  • 15