«Была обнаружена ошибка FatalExecutionEngineError» при использовании Console.Строка записи после переопределения строки.Пусто

#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){
}