5

I have a struct (.NET 3.5):

struct ColumnHeadings 
        { 
            public string Name ; 
            public int Width ; 
        } ;

And when I try to assign a list of values to that struct I get a 'cannot implicitly convert type string/int to ...':

private void doSomething()
{
    ColumnHeadings[,] ch = new ColumnHeadings[,]{{"column1",100},
                {"column2",100},{"column3",100}};
}

Can the struct values be assigned in the same way as a multi-dimensional array? Or do I need to assign the values by using?:

ch.Name = "column 1";

UPDATE:

Thanks to Marc's excellent feedback the correct solution is:

Struct:

struct ColumnHeadings
        {
            private readonly string name;
            private readonly int width;
            public string Name { get { return name; } }
            public int Width { get { return width; } }
            public ColumnHeadings(string name, int width)
            {
                this.name = name;
                this.width = width;
            }
        } 

Then in the method:

 var ch = new[]{new ColumnHeadings("column1",100),
            new ColumnHeadings("column2",100),
            new ColumnHeadings("column3",100)};

And the link to why mutuable structs aren't a good idea.

Community
  • 1
  • 1
John M
  • 14,338
  • 29
  • 91
  • 143

1 Answers1

8

firstly, that probably shouldn't be a struct at all

The syntax will be:

ColumnHeadings[] ch = new ColumnHeadings[]{
    new ColumnHeadings{Name="column1",Width=100},
    new ColumnHeadings{Name="column2",Width=100}
};

However, in addition you have the issue of public fields, and the fact that this is a mutable struct - both of which are dangerous. No, really.

I would add a constructor:

var ch = new []{
     new ColumnHeadings("column1", 100),
     new ColumnHeadings("column2", 100)
};

with:

struct ColumnHeadings
{
    private readonly string name;
    private readonly int width;
    public string Name { get { return name; } }
    public int Width { get { return width; } }
    public ColumnHeadings(string name, int width)
    {
        this.name = name;
        this.width = width;
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • This makes a lot more sense, but his is multi-dimensional. How would it work with a 2-d array? – C. Ross Dec 01 '10 at 13:35
  • @CRoss - see my comment on the question; the 2-d is, IMO, an error – Marc Gravell Dec 01 '10 at 13:36
  • @Marc - why not using `public string Name { get; private set; }`? – Shadow The GPT Wizard Dec 01 '10 at 13:36
  • Doesn't it need to be `public ColumnHeadings(string name, int width) : this() { ... }` ? I'm pretty sure it does since it's a struct :) – myermian Dec 01 '10 at 13:37
  • @Shadow, because I don't like having to call `: this()` in the constructor each time. – Marc Gravell Dec 01 '10 at 13:38
  • @myermian no, it doesn't; that is only the case if you don't explicitly set every field during the constructor. I **do** set every field in the constructor, hence I don't need to call the `: this()`. As a side note - if the fields are public you don't actually even need to call a constructor - you can do: `SomeStruct val; val.Foo = 123; val.Bar = "abc";` - and as long as every field is set it will compile. – Marc Gravell Dec 01 '10 at 13:39