C# と .NET Framework の奇妙な部分を探索してください
ソフトウェア開発では、不可解なエッジケースに遭遇することがよくあります。この記事では、C# と .NET Framework の最も奇妙なエッジ ケースのいくつかを調査し、その異常な動作を明らかにします。
文字列常駐例外
次のコード スニペットを考えてみましょう:
<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>
直感的には、「new」キーワードは通常、新しいオブジェクトにスペースを割り当てるため、出力は False であると予想されます。驚くべきことに、このコードはテストしたすべてのフレームワーク バージョンで True を出力します。仕様では、新しいオブジェクトを常に作成する必要があると規定されていますが、これは特殊なケースになります。
Nullable 型の例外
このコードは、C# の複雑さをさらに示しています。
<code class="language-csharp">static void Foo<T>() where T : new() { T t = new T(); // ... (其他操作) // 此行引发NullReferenceException Console.WriteLine(t.GetType()); }</code>
謎はタイプTにあります。それを明らかにするには、コードを注意深く調べる必要があります。 Nullable<T>
構造体は null 許容値型を表し、ほとんどのメンバー メソッドをオーバーライドしますが、GetType()
はオーバーライドしません。したがって、GetType()
が呼び出されると、null 許容値が object
にキャストされ (結果は null)、結果は NullReferenceException
になります。
クラスのインスタンス化のトリック
次のコードでは、別の不可解なエッジ ケースが発生します。ここでは、T が参照型に制限されています。
<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>
優れたエンジニアリング設計により、このコードはリモート呼び出しと同様の間接的な方法を使用して解読できます。
<code class="language-csharp">class MyFunnyProxyAttribute : ProxyAttribute { // ... (重写) } [MyFunnyProxy] class MyFunnyType : ContextBoundObject { }</code>
カスタム プロキシ属性を定義し、null を返すように new()
呼び出しをリダイレクトすると、CanThisHappen
のアサーションが壊れます。これは、C# 言語と .NET ランタイムの非常に高い柔軟性と潜在的な落とし穴を示しています。
以上がC#と.NETの予期しない動作とコーナーケースは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。