Bart Friederichs
Bart Friederichs

Reputation: 33511

Return a constant string array

I created a string[] getter to get some information on a class. I want it to always return the same value, and not create a new object on each call.

I have it implemented now like this:

string[] _someStrings = { "foo", "bar" };
protected string[] someStrings {
    get {
        return _someStrings;
    }
}

which seem to be OK. However, my first inkling was to write it like this:

protected string[] someStrings {
    get {
        return { "foo", "bar" };
    }
}

but that doesn't work (I get the error ; expected).

Why?

(this is mainly a "getting-to-understand-C# question).

update I made a typo. I do not want to create a new object on each call.

Upvotes: 1

Views: 2213

Answers (3)

Grant Thomas
Grant Thomas

Reputation: 45083

As an alternate approach, may I suggest, if the contents are supposed to be constant, using a read-only collection instead, such that:

private readonly ReadOnlyCollection<string> UnderlyingReadOnlyStrings;

// populate the read-only collection, then...

public ReadOnlyCollection<string> ReadOnlyStrings {
  get { return UnderlyingReadOnlyStrings; }
}

The benefit here is that your collection truly is read-only. And practically constant. It can't be re-assigned to, and the contents cannot be altered. You could even declare the underlying collection as static and populate in a static constructor.

Your second example doesn't work, as previously explained, because you're trying to return an "inline array", so to speak, and the syntax is not correct, and if it were, you would be newing the array each time - which goes against your requirements.

Upvotes: 2

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174299

The correct syntax would be this:

return new [] { "foo", "bar" };

The reason is that the short syntax without new [] is only valid for an assignment.

As you correctly note in a comment, this will create a new object on every call. The only way to avoid this is with a field that stores the created instance and return that field. This is exactly the solution you already have.
Please note however, that this allows consumers to change the contents of the array and affect other consumers:

var a1 = foo.SomeStrings;
var a2 = foo.SomeStrings;
a1[0] = "Some other value";
Assert.Equal("Some other value", a2[0]); // will pass

Upvotes: 4

Artless
Artless

Reputation: 4568

Your syntax is incorrect. Try this:

protected string[] someStrings 
{
    get 
    {
        return new string[] { "foo", "bar" };
    }
}

You can't have const array, but you can have a readonly one that will work as you expect (can also be static, obviously):

public readonly string[] someStrings = { "foo", "bar" };

Upvotes: 1

Related Questions