Rozpoczęcie ze zmianą w systemie Windows Server 2012

Edytuj: Pierwotnie myślałem, że jest to związane z .NET Framework 4.5. Okazało się, że dotyczy to również .NET Framework 4.0.

Nastąpiła zmiana w sposobie obsługi ciągów w systemie Windows Server 2012, który staram się lepiej zrozumieć. Wygląda na to, że zachowanie StartsWith uległo zmianie. Problem jest odtwarzalny przy użyciu obu systemów .NET Framework 4.0 i 4.5.

W systemie .NET Framework 4.5 w systemie Windows 7 poniższy program drukuje „Fałsz, t”. W systemie Windows 2012 Server drukuje zamiast tego „True, t”.

internal class Program
{
   private static void Main(string[] args)
   {
      string byteOrderMark = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
      Console.WriteLine("test".StartsWith(byteOrderMark));
      Console.WriteLine("test"[0]);
   }
}

Innymi słowy, StartsWith (ByteOrderMark) zwraca wartość true bez względu na treść ciągu. Jeśli masz kod, który próbuje usunąć znacznik kolejności bajtów przy użyciu następującej metody, ten kod będzie działał poprawnie w systemie Windows 7, ale będzie drukował „est” w systemie Windows 2012.

internal class Program
{
  private static void Main(string[] args)
  {
     string byteOrderMark = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
     string someString = "Test";

     if (someString.StartsWith(byteOrderMark))
        someString = someString.Substring(1);

     Console.WriteLine("{0}", someString);
     Console.ReadKey();

  }

}

Zdaję sobie sprawę, że zrobiłeś już coś złego, jeśli masz w łańcuchu znaczniki kolejności bajtów, ale integrujemy się ze starszym kodem, który to posiada. Wiem, że mogę rozwiązać ten konkretny problem, robiąc coś podobnego do poniższego, ale chcę lepiej zrozumieć problem.

someString = someString.Trim(byteOrderMark[0]);

Hans Passsant zasugerował użycie konstruktora UTF8Encoding, który pozwala mi wyraźnie powiedzieć, aby emitował identyfikator UTF8. Próbowałem tego, ale daje ten sam rezultat. Poniższy kod różni się wyjściem między Windows 7 i Windows Server 2012. W Windows 7 drukuje „Wynik: Fałsz”. W systemie Windows Server 2012 drukuje „Wynik: Prawda”.

  private static void Main(string[] args)
  {
     var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
     string byteOrderMark = encoding.GetString(encoding.GetPreamble());
     Console.WriteLine("Result: " + "Hello".StartsWith(byteOrderMark));
     Console.ReadKey();
  }

Wypróbowałem również następujący wariant, który drukuje Fałsz, Fałsz, Fałsz w systemie Windows 7, ale Prawda, Prawda, Fałsz w systemie Windows Server 2012, co potwierdza, że ​​jest to związane z implementacją StartsWith na Windows Server 2012.

  private static void Main(string[] args)
  {
     var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
     string byteOrderMark = encoding.GetString(encoding.GetPreamble());
     Console.WriteLine("Hello".StartsWith(byteOrderMark));
     Console.WriteLine("Hello".StartsWith('\ufeff'.ToString()));
     Console.WriteLine("Hello"[0] == '\ufeff');

     Console.ReadKey();
  }

questionAnswers(1)

yourAnswerToTheQuestion