views:

138

answers:

2

Why in Boolean type there are two fields with the same value?

internal const int True = 1;
internal const int False = 0;
internal const string TrueLiteral = "True";
internal const string FalseLiteral = "False";

and

public static readonly string TrueString;
public static readonly string FalseString;

static Boolean()
{
    TrueString = "True";
    FalseString = "False";
}

in reflector generated code, methods don't use those strings but:

public string ToString(IFormatProvider provider)
{
    if (!this)
    {
        return "False";
    }
    return "True";
}

would't it be better to use those const values?

EDIT: in CIL there is no difference between using const strings and instance strings.

So when I declare a private const string = "a", wherever in the application "a" is used, Jitter uses const value, or is it only in const string's scope?

+4  A: 

A quick synopsis on the differences between 'const' and 'readonly' in C#:

const:

  • Can't be static.
  • Value is evaluated at compile time.
  • Initiailized at declaration only.

readonly:

  • Can be either instance-level or static.
  • Value is evaluated at run time.
  • Can be initialized in declaration or by code in the constructor.

(source)

Therefore, where you are seeing "False" hard-coded, it was simply substituted at compile-time from the FalseLiteral const.

Jon Grant
While mostly correct, saying that a constant "can't be static" is incorrect, as constants *are* (syntactically) static (I say syntactically, as there's never an actual static runtime call since they're evaluated at compile time). It's true that a constant cannot be *explicitly declared* `static`, but only because it's redundant and introduced the potential for confusion.
Adam Robinson
+2  A: 

The reason is that public const variables can be problematic if their values are later changed. Since their values are directly replaced in the CIL, you may end up with two assemblies using different values for the same const. To avoid this, the type only exposes readonly variables (TrueString and FalseString).

Internally, there is no problem: if you change the const values in the code, you will compile the assembly anyway. So this is the reason for the internal consts (TrueLiteral and FalseLiteral). This way, their assembly can take advantage of their higher speed.

Since const variables are directly replaced by their values in CIL, you cannot see them in your reflector generated code. But they are indeed used inside ToString.

Gorpik