Heim >Backend-Entwicklung >C++ >Was sind einige unerwartete Verhaltensweisen und Eckfälle in C# und .NET?
Entdecken Sie die seltsamen Ecken von C# und dem .NET Framework
In der Softwareentwicklung stoßen wir oft auf einige rätselhafte Grenzfälle. In diesem Artikel werden einige der bizarrsten Edge-Fälle in C# und dem .NET-Framework untersucht und ihr anomales Verhalten aufgedeckt.
String-residente Ausnahme
Bedenken Sie den folgenden Codeausschnitt:
<code class="language-csharp">string x = new string(new char[0]); string y = new string(new char[0]); Console.WriteLine(object.ReferenceEquals(x, y));</code>
Intuitiv würden wir erwarten, dass die Ausgabe False ist, da das Schlüsselwort „new“ normalerweise Platz für ein neues Objekt zuweist. Überraschenderweise gibt dieser Code in allen getesteten Framework-Versionen „True“ aus. Obwohl die Spezifikation besagt, dass immer neue Objekte erstellt werden sollen, stellt dies einen Sonderfall dar.
Ausnahme vom Typ Nullable
Dieser Code veranschaulicht die Komplexität von C# weiter:
<code class="language-csharp">static void Foo<T>() where T : new() { T t = new T(); // ... (其他操作) // 此行引发NullReferenceException Console.WriteLine(t.GetType()); }</code>
Das Geheimnis liegt im Typ T. Um es aufzudecken, müssen wir den Code sorgfältig untersuchen. Die Nullable<T>
-Struktur stellt einen nullbaren Werttyp dar, der die meisten Mitgliedsmethoden überschreibt, GetType()
jedoch nicht. Wenn also GetType()
aufgerufen wird, wird der nullbare Wert in object
umgewandelt (was zu Null führt), was zu NullReferenceException
führt.
Klassen-Instanziierungstrick
Ein weiterer rätselhafter Randfall tritt im folgenden Code auf, in dem T auf einen Referenztyp beschränkt ist:
<code class="language-csharp">private static void Main() { CanThisHappen<MyFunnyType>(); } public static void CanThisHappen<T>() where T : class, new() { var instance = new T(); Debug.Assert(instance != null, "我们是如何破坏CLR的?"); }</code>
Durch hervorragendes technisches Design kann dieser Code mithilfe indirekter Methoden, ähnlich wie bei Fernaufrufen, gebrochen werden:
<code class="language-csharp">class MyFunnyProxyAttribute : ProxyAttribute { // ... (重写) } [MyFunnyProxy] class MyFunnyType : ContextBoundObject { }</code>
Durch die Definition eines benutzerdefinierten Proxy-Attributs und die Umleitung des new()
-Aufrufs zur Rückgabe von Null wird die Behauptung in CanThisHappen
gebrochen, was die enorme Flexibilität und potenziellen Fallstricke in der C#-Sprache und der .NET-Laufzeit demonstriert.
Das obige ist der detaillierte Inhalt vonWas sind einige unerwartete Verhaltensweisen und Eckfälle in C# und .NET?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!