C# Static class vs struct for predefined strings

Viewed 26029

A co-worker just created the following construction in C# (the example code is simplified). His goal was to shorten the notation for all predefined strings in the rest of the code.

public struct PredefinedStrings
{
    public const string VeryLongName = "Very Long Name";
    public const string AnotherVeryLongName = "Another Very Long Name";
    public const string TheLastVeryLongName = "The Last Very Long Name";
}

public static void MethodThatUsesTheNames()
{
    Console.WriteLine(PredefinedStrings.VeryLongName);
    Console.WriteLine(PredefinedStrings.AnotherVeryLongName);
    Console.WriteLine(PredefinedStrings.TheLastVeryLongName);
}

Although it seems to work fine for him, I can't stop wondering whether he should have used a static class instead of a struct or if there's a more elegant way to achieve this.

What would be the preferred way to do this? Please also explain why.

13 Answers

With the struct solution, there's nothing to stop some other code doing new PredefinedStrings(), which won't do anything bad, but is something it's semantically confusing to allow. With a static class the compiler will forbid creation for you. And it goes without saying that static class is the preferred way of providing constants in the Framework.

edit to add, I said that second part without evidence - I have since searched and reasonably quickly found System.Net.Mime.DispositionTypeNames and System.Net.WebRequestMethods.Http.

I would prefer the strings all being in a resource file and not embedded within the code - primarily for internationalisation reasons. This can then be accessed via a static class with the values as property members.

Besides a static class and struct, why not consider using resource files for constant strings? These can be accessed very easily as SomeNamespace.ResourceName.KeyName, and depending on where they are located in your project can be managed externally without recompiling if need be...

Simple rule of thumb: never use structs until you have no other choice.

Constants have a couple of drawbacks:

  • only simple types can be used (strings, numerics, etc.)
  • constants are injected into referencing assemblies. If you recompile assembly with constants and don't recompile assembly that uses constants, you'll get into trouble

I would write your code like this (notice rename refactoring too):

public static class KnownNames
{
    public static readonly string VeryLong = "Very Long Name";
    public static readonly string AnotherVeryLong = "Another Very Long Name";
    public static readonly string TheLastVeryLong = "The Last Very Long Name";
}

There is nothing functionally wrong with this code. But stylistically I agree a static class is better. A static class declares the intent of the type is to only hold static / constant data.

It sounds like you're looking for a resource file (.resx). It's a decent place to store such strings, and abstracting your strings into a .resx will make it easier to localize your application in the future. The MSDN page at http://msdn.microsoft.com/en-us/library/1ztca10y.aspx is a decent start for more information.

ETA: Thank you to Dennis19901: since these strings are const, they will not actually take up any space. The struct will consume 1 byte only.

OLD AND BUSTED INFO: Don't forget the recommendation that a struct size should be about 16 bytes. Given a 32-bit system, that's 4 System.String references right there. I'd say you're better off with a static class if the number of strings will increase.

I think static is better and here's my reasoning. If this code lives in some library, and another piece of code consumes this library, if the value of the constant fields change, then not only will this library need to be recompiled (duh) but you'll have to recompile the code consuming this library as well. The reason for that is, the compile inserts the constant values wherever you reference them. If you use static though, you won't have this problem, as you're referencing the field not the value.

In my practice for this purpose we use Dictionary<enumNameType, string>. Where enumNameType is the different type of names you can have (in your case) ... This dictionary is wrapped in a static class and is cached - we create it just the first time we use it and then return the same object ...

I hope this will be useful for you, too!

I use structs for constants too, but only for internal use, not for public APIs. It feels natural since enums are also converted to structs.

Related