Interesting. I assume you aware that Microsoft's standards
specifically dictate that you do not use these prefixes.
Of course I'm aware of the Microsoft standards. However, AFAICT, Microsoft's
naming guidelines are really only for public-visibly fields. They are intended
to allow client code to have a consistent experience when using any .NET
API.
IMO, any static or instance field should be private. To do otherwise would
break good encapsulation practice and a bad idea (the only exception is using
a static, read-only field for a predefined object instance). If you *do*
have protected or public fields, you should certainly follow Microsoft's
guidelines for consistency. But, since I don't do that, I choose to use my
own conventions.
If you use the .NET Reflector to example the BCL assemblies, you'll find
that Microsoft also does the same thing. For example, looking at System.ApplicationId
reveals the following fields:
private string m_culture;
private string m_name;
private string m_processorArchitecture;
internal byte[] m_publicKeyToken;
private Version m_version;
But, it's not consistent. System.Guid has these fields:
public static readonly Guid Empty;
private int _a;
private short _b;
private short _c;
private byte _d;
private byte _e;
private byte _f;
private byte _g;
private byte _h;
private byte _i;
private byte _j;
private byte _k;
System.String:
private const int alignConst = 3;
private const int charPtrAlignConst = 1;
public static readonly string Empty;
[NonSerialized]
private int m_arrayLength;
[NonSerialized]
private char m_firstChar;
[NonSerialized]
private int m_stringLength;
private const int TrimBoth = 2;
private const int TrimHead = 0;
private const int TrimTail = 1;
internal static readonly char[] WhitespaceChars;
System.Collections.ArrayList:
private const int _defaultCapacity = 4;
private object[] _items;
private int _size;
[NonSerialized]
private object _syncRoot;
private int _version;
private static readonly object[] emptyArray;
So, Microsoft only consistently follow convention when the field is going
to be consumed as an API. In fact, they sometimes even break that. Consider
the fields from System.Diagnostics.StackTrace:
private StackFrame[] frames;
private int m_iMethodsToSkip;
private int m_iNumOfFrames;
public const int METHODS_TO_SKIP = 0;
Notice that there's a public constant in ALL CAPS. Oops!
Microsoft *does* have this statement in the Field Usage Guidelines document
(
http://msdn.microsoft.com/library/d...s/cpgenref/html/cpconfieldusageguidelines.asp):
"Do not apply a prefix to field names or static field names. Specifically,
do not apply a prefix to a field name to distinguish between static and nonstatic
fields. For example, applying a g_ or s_ prefix is incorrect."
However, consider the following quote from "Framework Design Guidelines:
Conventions, Idions, and Patterns for Reusable .NET Libraries", Section 3.6.4
("Naming Fields"), pg. 64:
"The field naming guidelines apply to static public and protected fields.
Internal and private fields are not covered by guidelines and public or protected
instance fields are not allowed according to the member design guidelines
described in Chapter 5."
Last in the same section, it says "do not use 'g_' or 's_' to distinguish
static versus non-static fields". However, it already specified that the
guidelines do not apply to private fields.
Personally, I see distinguishing between static and instance fields as a
very useful convention. It can reduce mistakes and increase usability if
you are looking at a method that contains code which mixes instance and static
field access. The desire to distinguish fields from locals and parameters
is driven by the same purpose. So, unless Microsoft actually publishes a
*reason* (e.g. disadvantage) to name static and instance fields the same,
I'm going to continue to distinguish them.
Even Jeffrey Richter prefixes with "m_" and "s_" in the CLR via C# book for
private instance and static fields respectively (cf pg. 180).
And finally, to find a case where Microsoft distinguishes between instance
and static fields, you don't have to look any further than System.Threading.Thread:
private IntPtr DONT_USE_InternalThread;
private Context m_Context;
private CultureInfo m_CurrentCulture;
private CultureInfo m_CurrentUICulture;
private Delegate m_Delegate;
private ExecutionContext m_ExecutionContext;
private string m_Name;
private int m_Priority;
private object m_ThreadStartArg;
private int[] m_ThreadStaticsBits;
private object[][] m_ThreadStaticsBuckets;
private static LocalDataStoreMgr s_LocalDataStoreMgr;
private static object s_SyncObject;
private const int STATICS_BUCKET_SIZE = 0x20;
Best Regards,
Dustin Campbell
Developer Express Inc.