#c# #visual-studio-2010 #clr
#c# #visual-studio-2010 #clr
Вопрос:
Я пытаюсь (для развлечения) переопределить, String.Empty
чтобы это был один пробел «". Почему это нарушает структуру CLR?
Сообщение:
Среда выполнения обнаружила неустранимую ошибку. Адрес ошибки был 0x5814b976, в потоке 0xf40. Код ошибки 0x80131623. Эта ошибка может быть ошибкой в CLR или в небезопасных или не поддающихся проверке частях пользовательского кода. Распространенные источники этой ошибки включают ошибки маршалинга пользователя для COM-interop или PInvoke, которые могут повредить стек.
Как воспроизвести:
class Program
{
static void Main()
{
typeof(string).GetField("Empty").SetValue(null, " ");
Console.WriteLine("{}", "");
}
}
Комментарии:
1. Я не очень уверен .. но разве вам это не нужно
{0}
там? а также указатьstring.Empty
2. @V4Vandetta прав, ввод {0} устраняет проблемы. Но в любом случае это странное сообщение об ошибке.
3. Попробуйте этот код : typeof (строка). getField("Пустое"). setValue(null, "Тест"); Консоль. WriteLine("{0}", Строка. Пусто); Вы получаете: TestTest, кажется, что фреймворки добавляют дополнительную строку. Пустой в начале каждой строки.
4. Думаю, они используют его как фиктивный в реализации "null object patern" ( en.wikipedia.org/wiki/Null_Object_pattern ). Поэтому нет ничего странного в том, что она добавлена на передний план.
Ответ №1:
Если мы посмотрим на программу
class Program
{
static void Main()
{
Console.WriteLine("{}", "");
}
}
затем произойдет сбой с FormatException
сообщением об ошибке Input string was not in a correct format
.
Однако, когда мы вставляем typeof(string).GetField("Empty").SetValue(null, " ");
перед строкой с Console.WriteLine
, код завершается ошибкой при попытке найти это сообщение об ошибке. Если мы посмотрим на полную трассировку стека (включая "Показать внешний код"), то увидим, что код завершается с ошибкой System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(string fileName = " mscorlib.resources")
(обратите внимание на пробел перед mscorlib.resources).
Причина этого в том, что для поиска файла ресурсов ManifestBasedResourceGroveler
используется метод GetResourceFileName
из ResourceManager
. И в GetResourceFileName
мы используем a StringBuilder
для создания имени файла, а конструктор StringBuilder
начинается с String.Empty
.
public StringBuilder(int capacity)
: this(String.Empty,capacity){
}