Почему это не строка.Пустая константа?
в .Net почему строка.Пустой только для чтения вместо константы? Мне просто интересно, знает ли кто-нибудь, какие причины стояли за этим решением.
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: 59tvanfosson просто объяснил это немного подробнее. "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