Q:

What is the difference between String.Empty and "" (empty string)?

In .NET, what is the difference between String.Empty and "", and are they interchangable, or is there some underlying reference or Localization issues around equality that String.Empty will ensure are not a problem?

A:

In .NET prior to version 2.0, "" creates an object while string.Empty creates no objectref, which makes string.Empty more efficient. 
In version 2.0 and later of .NET, all occurrences of "" refer to the same string literal, which means "" is equivalent to .Empty, but still not as fast as .Length == 0.
.Length == 0 is the fastest option, but .Empty makes for slightly cleaner code.
See the .NET specification for more information.

A:

what is the difference between String.Empty and "", and are they
  interchangable

string.Empty is a read-only field whereas "" is a compile time constant. Places where they behave differently are: 
Default Parameter value in C# 4.0 or higher
void SomeMethod(int ID, string value = string.Empty)
// Error: Default parameter value for 'value' must be a compile-time constant
{
    //... implementation
}

Case expression in switch statement
string str = "";
switch(str)
{
    case string.Empty: // Error: A constant value is expected. 
        break;

    case "":
        break;

}

Attribute arguments
[Example(String.Empty)]
// Error: An attribute argument must be a constant expression, typeof expression 
//        or array creation expression of an attribute parameter type

A:

The previous answers were correct for .NET 1.1 (look at the date of the post they linked: 2003).  As of .NET 2.0 and later, there is essentially no difference.  The JIT will end up referencing the same object on the heap anyhow.
According to the C# specification, section 2.4.4.5:
http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx

Each string literal does not necessarily result in a new string instance. When two or more string literals that are equivalent according to the string equality operator (Section 7.9.7) appear in the same assembly, these string literals refer to the same string instance.

Someone even mentions this in the comments of Brad Abram's post
In summary, the practical result of "" vs. String.Empty is nil. The JIT will figure it out in the end. 
I have found, personally, that the JIT is way smarter than me and so I try not to get too clever with micro-compiler optimizations like that. The JIT will unfold for() loops, remove redundant code, inline methods, etc better and at more appropriate times than either I or the C# compiler could ever anticipate before hand.  Let the JIT do its job :)

