3

I am trying to write the following code:

public const Size ImageSize = new Size() { Width = 28, Height = 28 };

But I get the error that Width and Height are read-only.

What is the recommended way to do this?

Cody Gray
  • 222,280
  • 47
  • 466
  • 543
BrunoLM
  • 88,362
  • 76
  • 272
  • 427

7 Answers7

10

The fundamental problem is that you cannot declare an object of type System.Drawing.Size as const. That indicates that the symbol is to be replaced at compile-time with the value of the constant.

Instead, you should use readonly. This is also a "constant" value in the sense that it cannot be modified once the constructor has run, but the objects are created at run-time instead of compile-time.

The following code compiles just fine:

public static readonly Size ImageSize = new Size() { Width = 28, Height = 28 };
Cody Gray
  • 222,280
  • 47
  • 466
  • 543
9

const is restricted to primitives that the compiler can directly write as IL directly. readonly should suffice here if Size is treated as immutable, i.e.

public static readonly Size ImageSize = new Size(28,28);

Note that if Size is a mutable struct, bad things can happen; I would recommend a property rather than a field to prevent a number of confusing side-effects.

Marc Gravell
  • 927,783
  • 236
  • 2,422
  • 2,784
  • But System.Drawing.Size _is_ a mutable struct - http://stackoverflow.com/questions/14192527/why-are-system-drawing-rectangle-point-size-etc-mutable-structs-and-not-classe – Flash Jan 09 '13 at 07:28
  • @Andrew the `readonly` takes care of that in this case (you can't change fields in a `struct` marked `readonly`; the compiler doesn't let you). As for whether `Size` is a mutable struct: that depends on which `Size` we're talking about: the OP doesn't cite a namespace, and there are *several* `Size` types in the BCL, or you can of course define your own. – Marc Gravell Jan 09 '13 at 07:37
2
public static readonly Size ImageSize = new Size(28,28);
Jesper Larsen-Ledet
  • 6,365
  • 3
  • 28
  • 42
  • One line code with no explanation probably copied from previous answers is certainly a downvote. – BrunoLM Feb 22 '11 at 13:19
  • 2
    Pardon me, sir! I posted my answer first and when I saw other answers appearing that had the full explanation I moved on with my life. Please do the same. – Jesper Larsen-Ledet Feb 22 '11 at 13:25
1

You have to do this instead:

public readonly Size ImageSize = new Size(28, 28);

Making the instance read only to prevent it to be changed, as you cannot create Size as a constant.

From the docs:

A constant expression is an expression that can be fully evaluated at compile time. Therefore, the only possible values for constants of reference types are string and null.

Mikael Svenson
  • 36,831
  • 6
  • 68
  • 72
1

The code you're writing:

public const Size ImageSize = new Size() { Width = 28, Height = 28 };

Actually compiles down to the same as this:

public const Size ImageSize = new Size();
ImageSize.Width = 28;
ImageSize.Height = 28;

The version your using, called the object initializer, is just syntactic shorthand for the latter version above. The two are logically identical. In the latter version you can see why it's giving you the error, you can't set properties on a const after it's been declared.

More to the point, I'm not sure if you can even use a reference type like that as a const. I'm not sure about that, as I can't say I ever tried it. You may try readonly instead. Though you may run into the same or similar issue.

Does Size have a constructor you can call with the parameters, rather than using the object initializer?

David
  • 176,566
  • 33
  • 178
  • 245
  • @BrunoLM: Yes, `Size` certainly *does* have a constructor that takes the width and the height as arguments. That still won't solve your underlying problem, but it's worth knowing about nevertheless. – Cody Gray Feb 22 '11 at 13:16
0

You need to use a constructor that takes width and height as parameters. Also, the expression must be completely evaluable during compile time. That might not work with your Size type (don't know which one it is). If so (like with System.Drawing.Size), you might consider using readonly instead of const.

Botz3000
  • 37,236
  • 8
  • 100
  • 125
0

You can use :

public static readonly Size ImageSize = new Size(28, 28);

It's not actually a const, but it won't be changed after the initialization.

Steve B
  • 34,941
  • 18
  • 92
  • 155