4

I have a class like:

class SomeTests {
  private Guid[] someGuids = new Guid[] { ... }

  public void ThoseGuidsShouldAlwaysBeThere() {
    foreach (Guid g in someGuids) { // error appears here
        // ...
    }
  }
}

Semantically, I want someGuids to be const, since they shouldn't be updated, ever, except before recompiling the code. But adding the const keyword generates error CS0168: null is not valid in this context.

Reading the MSDN page for that error, it seems to me that the compiler thinks I'm doing this:

foreach (Guid g in null) {

I don't understand how adding const causes this problem here, and how to solve my semantic problem (list is read-only, not writable) -- keeping it as an array instead of a List is "almost" good enough.

2 Answers 2

3

The readonly keyword in this use is a bit misleading. Look at it as preventing the collection from being re-instantiated rather than modified.

Example:

 private readonly Guid[] someGuids = new Guid[] { Guid.NewGuid() };

 //This will not compile because it is read-only.
 someGuids = new Guid[] { Guid.NewGuid() };

 //This still compiles, and the first member will be changed
 someGuids[0] = Guid.NewGuid();

I recommend you look into using System.Collections.ObjectModel.ReadOnlyCollection<T> in combination with the readonly keyword instead.

Example:

    public readonly ReadOnlyCollection<Guid> someGuids = new
       ReadOnlyCollection<Guid>(new Guid[] { Guid.NewGuid(), Guid.NewGuid() });

The collection will no longer be able to be re-instantiated nor will its members be able to be modified.

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

1 Comment

This is NOT a compiler bug. It behaves exactly as it is supposed to act. If your goal is to prevent the guids from being changed once they're set, this is an option. The other falls short.
2

Trying to make Guid[] a constant should give you an error of "A const field of a reference type other than string can only be initialized with null."

Make it readonly instead:

private readonly Guid[] someGuids = new Guid[] { Guid.NewGuid() };

When it's readonly you can also assign the value in the constructor:

public SomeTests()
{
    someGuids = new[] { Guid.NewGuid(), Guid.NewGuid() };
}

As Jeffery mentioned in the comments, this solution prevents someGuids from being reassigned, but the items can still be modified. Jeffery addresses this issue in his answer.

5 Comments

I actually don't get the const-field-reference-type-nullz" error. Maybe it's a VS2008 bug; I can compile if I comment out my foreach iteration. Making it readonly and assigning the value out of the constructor works too.
This will not keep the collection from being modified, this will only keep it from being re-instantiated. You can still modify the members. E.g. someGuids[0] = new Guid();
@JefferyKhan that's right. Hardly warrants a downvote though. Question really has two parts to it.
Agreed, I'll remove it, however I would mention that piece. The OP stated they do not wish the guids to be able to be changed: since they shouldn't be updated, ever, except before recompiling the code
And unfortunately, I can't remove my downvote unless you edit your q.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.