开发者

Overzealous String Constants

I am sure this has been asked before, but in this example I am curious as to what usefulness others can see in separating constants to this degree:

public class CoreStringConstants
 {
  // Common strings
  public const string SPACE = " ";
  public const string PERIOD = ".";
  public const string COMMA = ",";
  public const string COLON = ":";
  public const string SEMI_COLON = ";";
  public const string HYPHEN = "-";
  public const string UNDER_SCORE = "_";
  public const string LEFT_BRACKET = "(";
  public const string RIGHT_BRACKET = ")";
  开发者_开发知识库  public const string LEFT_SQUARE_BRACKET = "[";
    public const string RIGHT_SQUARE_BRACKET = "]";
    public const string LEFT_CURLY_BRACKET = "{";
    public const string RIGHT_CURLY_BRACKET = "}";
    public const string PIPE = "|";
    public const string CIRCUMFLEX = "^";
    public const string ASTERISK = "*";

... Really?

Is there really any benefit to separating these kinds of string constants from your code?

When is the character used for ASTERISK going to change in the foreseeable lifetime of the application?


Actually, I'd consider this a disadvantage. Benefits are dubious to say the least, especially since there is support for pooling string literals anyway, and as a developer I'd have to look up the value of each constant when I encounter code like this for the first time.

Additionally, someone will come up with code that reads

public const string COLON = "*";


In the example you provided, the constants are useless, because as you said, ASTERISK is always going to be *.

It would make a lot more sense to name them after their actual purpose. For example, if you used parentheses to group something in your strings, you could write:

public const string GROUP_START = "(";
public const string GROUP_END = ")";

In this case, it makes sense because the grouping characters could change tomorrow to, say, square brackets.


I can't think of a single reason why these string constants need to be defined. Maybe the original author thought that there would be some memory savings by defining the strings once, but the C# compiler is smart enough to intern strings. (e.g. Identical string constants will be output once into the assembly's .DATA section.)

var space1 = " ";
var space2 = " ";
Console.WriteLine(Object.ReferenceEquals(space1, space2));  // Outputs true

So there is honestly no good reason for CoreStringConstants.


There are several reasons why someone might want to do this (although there's no need to SHOUT all the constants in this day and age!). However, it is unlikely that there are many good reasons for the particular defines you have listed.

  • Different character encodings may mean that some of the constants could change. Yes, it is "possible" that in a particular character encoding, "asterisk" isn't the same as an ASCII "". Maybe in Chinese a different character may be preferable to "". Is it likely? Well, perhaps not... but having these values in constants will make refactoring easier.

  • Depending on the usage, using a constant allows the character used to be changed throughout the code for easier refactoring. However, in this case I would say those constants are poorly named (e.g. if a curly brace represents the start of a scope, "start scope" would be a better name than "curly brace", allowing you to redefine your system to use (e.g) angle brackets instead of curly brackets to start a scope without the name of the constant becoming confusing)

  • The programmer may have thought that he might refactor to use either strings or chars in future, and by using constants, this choice is easier to refactor later. Of course, one should have more confidence in one's designs than that :-)

  • Perhaps the programmer thinks that constants will cause all the strings to be shared rather than duplicated. String interning usually makes this an unnecessary optimisation.

  • Named constants are often more meaningful than inlined magic constants, and are less prone to typos - this is the only "good" reason I can think of.


No this doesn't help but this may come from the advice in Steve McConnel's Code Complete section 12.7 Named Constants. Specifically he writes

Avoid literals, even "safe" ones In the following loop what do you think the 12 represents?

Visual Basic Example of Unclear Code

For i = 1 to 12

   profit( i ) = revenue (i ) = expense ( i )

Next

Then he later shows that it would be better to replace 12 with NUM_MONTHS_IN_YEAR or to do from Month_January to Month_Decemener

That's all well and good but the advice fails to make an exception for when you're using a string to that has meaning and aren't magic. For example SQL strings and regular expressions and HTML and CSS strings have meaning and the meaning should be well known to the user.

This kind of thing seems to be a specific case for this question


The only benefit would be that writing CoreStringConstants.SPACE would be a bit clearer and less prone to unnoticed typos than " ". Other than that there is not really any good reason for doing something like that.

As you point out, none of these will ever change, so there is no such reason to centralise the definitions.

Oh, and using all upper case for identifiers is just horrible.


If you have preprocessor directives around them you could specify different sets of them depending on your build. This would be helpful in a large text processing environment which needs to be language agnostic (especially in cases where punctuation marks are used differently).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜