1

I have a static string class for my database so that I always spell the tables and columns they way they were designed.

I've currently got about 500 lines of code in this one class, but here is a short example:

public const string PURCHASING = "PURCHASING";
public const string SCHED_PURCH = "SCHED/PURCH";
public const string SCHEDULING = "SCHEDULING";

To create a readonly static string array of the "Clerk" department, I use this static declaration:

public static string[] CLERK_DEPT {
  get {
    return new string[] { PURCHASING, SCHEDULING, SCHED_PURCH };
  }
}

There are many lines of code like this in my database strings class.

Today, I happened across this active post where someone was doing something very similar:

How do I prevent the modification of a private field in a class?

The answer there provided a way to provide a readonly string array that I had not considered before:

You must return a copy of your array.

public String[] getArr() {
  return arr == null ? null : Arrays.copyOf(arr, arr.length);
}

That has me wondering now if someone out here knows of a more efficient way of passing back my readonly string array.

I must admit that I've always abhorred the idea of the return new string[] in my code.

So, is there? ...a more efficient and cleaner way of doing this or have I already created the best solution?

5
  • Try using an enumeration. In C# this is the best option. Commented Feb 11, 2013 at 16:44
  • @DJKRAZE Good suggetstion, but it looks like enumeration would not bring much in such case (unless individual columns need to be accessed by name directly instead of "all columns from ..."). And there will be almost no space benefit compared to enums as string take pointer-size space to be stored in copy of an array which is at worst 2x compared to 4 bytes for regular enum. Commented Feb 11, 2013 at 17:02
  • I understand Alexei but personally I can't tell what the OP is trying to do.. the only reason that I have suggested the Enumeration or enum is because I knew personally how my structure was and I've set plenty of projects up using this approach. thanks for the additional information as well.. Commented Feb 11, 2013 at 17:14
  • @DJKRAZE: These are for database calls. So, after I read employee records, I can tell if someone is a Clerk by checking if that row's DEPT field is contained in the CLERK_DEPT array (which should be readonly). Commented Feb 11, 2013 at 17:22
  • how many times are you making the database call(s) looking at the 2 posted answers John Skeet's answer seems to make the most sense not to mention that he's given a working example as well. jp2Code also you stated that by checking rows DEPT perhaps you can share the code that you are using an someone see what it is that you are trying to do since you are concerned with additional overhead if any Commented Feb 11, 2013 at 17:29

2 Answers 2

6

There's no such thing as an immutable array, basically.

If you trust all your callers, you could tell them not to mutate the array. An alternative is to provide a read-only wrapper:

private static readonly ReadOnlyCollection<string> clerkDepartments =
    new ReadOnlyCollection<string>(
        new[] { "PURCHASING", "SCHED/PURCH", "SCHEDULING" });

public static readonly ReadOnlyCollection<string> ClerkDepartments
    { get { return clerkDepartments; } }

Note that although ReadOnlyCollection<T> isn't a totally immutable collection, only code with access to the underlying collection could change it - and as the only code which "knows" about the array is the initializer which passes it to the constructor, you're basically safe unless someone cracks out reflection :)

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

2 Comments

And the same can be written as Array.AsReadOnly(new[] { "PURCHASING", "SCHED/PURCH", "SCHEDULING", }).
Is the ReadOnlyCollection<T> any more efficient than what I am currently doing? Or, more importantly, is there anything bad about what I am currently doing (i.e. memory leak)?
3

Perhaps use a ReadOnlyCollection?

http://msdn.microsoft.com/en-us/library/ms132474.aspx

1 Comment

+1, but looking for more reasoning or justification to use this. The ReadOnlyCollection has some overhead to it. Would this be less efficient than the way I do it now?