3

Which one should I use?

This:

public class MyClass
{
    static string m_MyString = "My string here";
    public static string MyString { get { return m_MyString; } }
}

Or this:

public class MyClass
{
    public static readonly string MyString = "My string here";
}
Rollor
  • 601
  • 1
  • 7
  • 17
  • 1
    Neither of these are global... – Basic Mar 08 '11 at 10:26
  • What is the purpose? Will it just contain hard-coded strings that are not to be changed, or will they get changed by other code? Are those strings indended for the user or just for the code? – Fredrik Mörk Mar 08 '11 at 10:30
  • They will hold hard-coded strings. T-Sql Queries if you're curious. – Rollor Mar 08 '11 at 10:33
  • "Better practice" according to *what*? – Cody Gray - on strike Mar 08 '11 at 10:35
  • @Rollo: yes I am curious, because the intended use might make a huge difference on the better approach to use. I see in another comment that you can't use stored procs. All this is information that makes a huge difference in suggested responses (I spent a some time writing a quite elaborate answer on a better approach based on converting the queries to SPs; wasted time unfortunately). – Fredrik Mörk Mar 08 '11 at 10:44
  • 1
    @Fredrik Mörk: Thank you for your time to answer. Sorry if my questions are not very in depth, I'm quite new to StackOverflow and I am being overwhelmed by the super quick response time, I'm getting multiple answers before I get to further specify my questions. Kinda like "optimistic concurrency" lol – Rollor Mar 08 '11 at 11:00
  • @Rollo: I know, SO is incredible in that sense. Sorry if my tone was a bit harsh there, that was not my intention :-) – Fredrik Mörk Mar 08 '11 at 11:50

3 Answers3

1

Use the latter, but with a slight modification:

public static class CommonStrings
{
    public const string MyString = "My string here";
}

On another note, 'global' variables have the stigma of being bad practice - however, in this instance a common container for reusable strings is preferable in my opinion; I wouldn't go around making everything you want to reuse publicly accessible, though, particularly if they're not constant.

Grant Thomas
  • 44,454
  • 10
  • 85
  • 129
  • 4
    be aware that declaring it as const will cause the value to be compiled into any other dlls that reference it, meaning that if you were to update the value of MyString in a new version of your dll, no other dlls that reference it would see the update without being recompiled. [See here](http://stackoverflow.com/questions/755685/c-static-readonly-vs-const) for more details on the difference between const and readonly and the consequences of using each. – Sam Holder Mar 08 '11 at 10:30
  • @Sam: Excellent point, though still warranted for constant values. – Grant Thomas Mar 08 '11 at 10:45
1

I would say neither. Rhetorical questions to to ask yourself to help with your decision: Where are they used? Can't they be declared private in the class that uses them? If used by several classes, perhaps those classes can hold a reference to MyClass? Are there any operations associated with the strings that can be put inside the MyClass?

vidstige
  • 12,492
  • 9
  • 66
  • 110
  • They will contain hard-coded strings to be used by other objects in the program. To be specific, they will contain T-SQL queries (there are about 80+ queries). It is to be written in a separate .cs file so the SQL guy can just copy-paste his queries there. Unfortunately, we can't work with Stored Procs or LINQ because the DB for this project is MySQL 4. – Rollor Mar 08 '11 at 10:40
1

If you only need to share such strings in your code, I would suggest you to use resources (resx) instead of reinventing the wheel.

Just create a resource and use it.

In the other hand, if you're looking to share common values, I would suggest you to create something like an environment class, like one found in .NET class library called "CustomEnvironment" (change "Custom" with any identifier that would be reasonable for you).

This "environment" provides access to common resources, platform-specific information and methods that would format, convert or accomodate any data or object to the platform.

You should avoid "global variables" way of doing things, and classes that are breaking any chance of a good OOP graph. Because "classes of constants" are a good shortcut for quickly doing things, but how you can answer to the question of "what this class represents in your object model?":

  • It's a group of variables: wrong, this isn't a class, because these variables (or constants, or properties) have no meaning: you could implement them in this class or in any other one.

  • It's a class of tools: "do all" tool classes that would move all "common" properties and behaviors to a class so all others are accessing to it for some critical operations isn't OOP, it's just grouping.

  • It's a set of resources. Ok, you don't need to reinvent the wheel, just use out-of-the-box resource-managing facilities in the Microsoft .NET class library.

  • It's just an example. Bad example ;)

So, just answering the question, accepting "global variables" are a bad approach in OOP, you should use constants if the exposed value isn't calculated or it doesn't need any processing, so, you can define it and it'll be assigned during class' construction time.

Perhaps you need to calculate or process something before setting such "constant": you'll use a readonly field, but, for me - just an opinion -, I'll suggest you to use a property in order to expose its value (maybe you won't need such readonly field, because sometimes you'll prefer to calculate/process each time code access to the property, but if you always do it with properties, you can encapsulate this implementation detail).

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • Thank you, this seems to be very logical. Then all I need to to to access the queries is to type: Resources.MyGlobalResourceFile.MyResourceName.ToString(); – Rollor Mar 08 '11 at 11:19