Почему не стринг?Пустая константа?

в .Net почему строка.Пустой только для чтения вместо константы? Мне просто интересно, знает ли кто-нибудь, что стояло за этим решением.

4 ответов


причина static readonly вместо const должен использоваться с неуправляемым кодом, как указано Microsoft здесь в Общий Источник Общая Языковая Инфраструктура 2.0 Release. Файл для просмотра -sscli20\clr\src\bcl\system\string.cs.

пустая константа содержит пустую строковое значение. Нам нужно позвонить String конструктор так, что компилятор не помечает это как буквальный.

маркировка этого как литерала означала бы что это не показать как поле который можно открыть из родной.

Я нашел эту информацию из эта удобная статья в CodeProject.


Я думаю, что здесь много путаницы и плохих ответов.

прежде всего,const поля static члены (Не члены экземпляра).

проверьте раздел 10.4 константы спецификации языка C#.

хотя константы считаются статические члены, константа-объявление ни требует, ни позволяет статический модификатор.

если public const члены статичны, нельзя рассматривать что константа создаст новый объект.

учитывая это, следующие строки кода ровно то же самое и в отношении создания нового объекта.

public static readonly string Empty = "";
public const string Empty = "";

вот заметка от Microsoft, которая объясняет разницу между 2:

ключевое слово readonly отличается от ключевое слово const. Поле const может инициализироваться только при объявлении поля. Поле readonly может быть инициализировано либо при объявлении или в конструкторе. Следовательно, поля readonly могут иметь разные значения в зависимости от конструктора используемый. Кроме того, в то время как поле const является в константа времени компиляции, только чтение поле может использоваться для выполнения константы. ,..


String.Empty read only instead of a constant?

если вы делаете любую строковую константу, затем компилятор заменяется на фактически строка везде, где вы его вызываете, и вы заполняете свой код одной и той же строкой, и когда код запускается, также нужно снова и снова читать эту строку из разных данных памяти.

если вы оставите строку читать только на одном месте, как это String.Empty, программа держит такую же строку только на одном месте и читает ее, или ссылается к ей-держать данные в памяти минимальные.

также, если вы компилируете любую dll, используя строку.Пусто, как const, и по какой-то причине строка.Пустое изменение, тогда скомпилированная dll больше не будет работать одинаково, потому что cost сделайте внутренний код, чтобы фактически сохранить копию строки при каждом вызове.

посмотреть этот код, например:

public class OneName
{
    const string cConst = "constant string";
    static string cStatic = "static string";
    readonly string cReadOnly = "read only string";

    protected void Fun()
    {
        string cAddThemAll ;

        cAddThemAll = cConst;
        cAddThemAll = cStatic ;
        cAddThemAll = cReadOnly;    
    }
}

будет приходить компилятором как:

public class OneName
{
    // note that the const exist also here !
    private const string cConst = "constant string";
    private readonly string cReadOnly;
    private static string cStatic;

    static OneName()
    {
        cStatic = "static string";
    }

    public OneName()
    {
        this.cReadOnly = "read only string";
    }

    protected void Fun()
    {
        string cAddThemAll ;

        // look here, will replace the const string everywhere is finds it.
        cAddThemAll = "constant string";
        cAddThemAll = cStatic;
        // but the read only will only get it from "one place".
        cAddThemAll = this.cReadOnly;

    }
}

и сборка вызов

        cAddThemAll = cConst;
0000003e  mov         eax,dword ptr ds:[09379C0Ch] 
00000044  mov         dword ptr [ebp-44h],eax 
        cAddThemAll = cStatic ;
00000047  mov         eax,dword ptr ds:[094E8C44h] 
0000004c  mov         dword ptr [ebp-44h],eax 
        cAddThemAll = cReadOnly;
0000004f  mov         eax,dword ptr [ebp-3Ch] 
00000052  mov         eax,dword ptr [eax+0000017Ch] 
00000058  mov         dword ptr [ebp-44h],eax 

изменить: Исправлена опечатка


этот ответ существует для исторических целей.

изначально:

, потому что String является классом и поэтому не может быть константой.

Расширенное Обсуждение:

много полезного диалога было забито в проверке этого ответа, и вместо того, чтобы удалить его, это содержимое воспроизводится напрямую:

в .NET (в отличие от Java) строка и строка абсолютно одинаковы. И да, вы можете иметь строковые литеральные константы в .NET-DrJokepu Feb 3 ' 09 В 16: 57

вы говорите, что класс не может иметь констант? – StingyJack 3 фев '09 В 16:58

да, объекты должны использовать только для чтения. Только структуры могут делать константы. Я думаю, когда вы используете string вместо String компилятор изменяет const в readonly для вас. Все это связано с тем, чтобы программисты Си были счастливы. - Гарри Шатлер Февраль 3 ' 09 В 16: 59

tvanfosson просто объяснил немного подробнее. "X не может быть константой, потому что содержащее Y-класс" было немного слишком контекстно-свободным ;) – Leonidas Feb 3 '09 В 17:01

строку.Empty-статическое свойство, возвращающее экземпляр класса String, а именно пустую строку, а не сам класс string. - tvanfosson Февраль 3 ' 09 В 17: 01

Empty является экземпляром только для чтения (это не свойство) класса String. - senfo Feb 3 ' 09 В 17: 02

голова болит. Я по-прежнему думаю, что права, но теперь уже не так уверена. Исследование требуется сегодня вечером! - Гарри Шатлер Февраль 3 ' 09 В 17: 07

пустая строка является экземпляром класса String. Пустое-это статическое поле (не свойство, я исправлен) в классе String. В основном разница между указателем и тем, на что он указывает. Если бы это было не только чтение, мы могли бы изменить, к какому экземпляру относится пустое поле. - tvanfosson Февраль 3 ' 09 в 17:07

Гарри, тебе не нужно проводить никаких исследований. Думать об этом. String-это класс. Пустой экземпляр строки. - senfo Feb 3 ' 09 В 17: 12

есть что-то, что я не совсем понимаю: как статический конструктор класса String может создать экземпляр класса String ? Разве это не какой-то сценарий" курицы или яйца"? - DrJokepu Февраль 3 ' 09 В 17: 12 5

этот ответ был бы правильным почти для любого другого класса, но Система.Строка. .NET делает много производительности специального корпуса для строк, и один из них заключается в том, что вы можете иметь строковые константы, просто попробуйте. В этом случае у Джеффа Йейтса есть правильный ответ. - Джоэл Мюллер Февраль 3 ' 09 в 19: 25

как описано в §7.18, а константное выражение-это выражение, которое может быть полностью вычислено во время компиляции. Поскольку единственным способом создания ненулевого значения ссылочного типа, отличного от string, является применение оператора new, и поскольку оператор new не допускается в константном выражении, единственное возможное значение для констант ссылочных типов, отличных от string, - null. Предыдущие два комментария были взяты непосредственно из спецификации языка C# и повторяют то, что упомянул Джоэл Мюллер. – senfo 4 фев '09 в 15:05 5