Introduction
One of the best coding practices suggests using String.Empty
rather using "" (empty string) as this will improve code readability and result in better managed execution. Using String.Empty
over "" is still debatable for several reasons.
In this article, I tried getting more technical details on how String.Empty
works under the hood.
Please note, this article is not trying to propose any recommendations.
The Real Difference
The first thing is, is there any real technical difference between "" and String.Empty
? When I checked Shared Source Common Language Infrastructure code files release by Microsoft, here is what I found:
public static readonly String Empty = "";
Now this clearly tells us that String.Empty
is just an alternative for "". Since Empty public
variable is static
readonly, it will not create a new string
object, instead CLR would use the reference for an existing one which is beneficial with respect to memory management.
Couple of things to notice here. All managed string
s are subject to "interning" which manages having only one object in memory which will hold the value "" and for every usage of "" will refer to the same object. Interning happens in the core part of CLR. Thinking on these lines, we may conclude that using "" or String.Empty
makes no technical difference. But there are few more things to have a look at.
String.Empty
resides in managed assembly mscorlib.dll. If we don't see this DLL referred in our project, we can ensure this by checking the assembly manifest after successfully compiling the project.
Does CLR load mscorelib.dll every time when an assembly is subject to run? In that case, using String.Empty
introduces the burden of taking a value from another assembly. But CLR handles this assembly in a different way.
Before the CLR executes the first line of managed code, it creates three application domains (System Domain, Shared Domain and Default Application Domain). Two of these (System and Shared) are opaque from within the managed code and are not even visible to CLR hosts. They can only be created through the CLR bootstrapping process facilitated by the shim—mscoree.dll and mscorwks.dll. These two are unmanaged assemblies.
The SystemDomain
is responsible for creating and initializing the SharedDomain
and the default AppDomain
. It loads the system library mscorlib.dll into SharedDomain
which is accessible to multiple application domains.
The System domain and the Shared domain are singleton and multiple app domains make use of these. Though we see mscorlib
in the manifest of every .NET component, it will not get loaded every time (since it is a single shared instance) like our custom (or application specific private) assemblies.
Whereas declaring and using const string
or string
with "" value will be a part of its own application domain. If we are running multiple .NET applications with their default application domain, we will see multiple (private) copies of string
literals in each domain.
History
- 30th September, 2007: Initial post
Pavan Gayakwad - a Dot Net Programmer with 3+ years of industry experience.