Почему это не строка.Пустая константа?


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

4 168

4 ответа:

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

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

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

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

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

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

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

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

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

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

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

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

ключевое слово readonly отличается от ключевое слово const. Поле const может инициализируется только при объявлении поля. Поле только для чтения может быть инициализируется либо при объявлении или в конструкторе. Следовательно, только для чтения поля могут иметь разные значения в зависимости от конструктора используемый. Кроме того, в то время как поле 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 at 16: 57

вы говорите, что класс не может иметь константы? - Скупердяй 3 февраля ' 09 В 16: 58

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

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

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

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

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

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

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

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

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

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