C# 和 .NET:揭開隱藏的驚喜
軟件開發經常會揭示意想不到的行為。 C# 和 .NET 雖然功能強大,但也不例外。 本文探討了一些有趣的極端案例,即使是經驗豐富的開發人員也會面臨挑戰。
字符串創建:違反直覺的結果
考慮這個看似簡單的代碼片段:
<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>
輸出為True
,與new
為引用類型創建不同對象的預期相矛盾。 公共語言運行時 (CLR) 優化了這一特定場景,重用相同的空字符串實例。
泛型類型和可為 Null
以下代碼演示了另一種意外行為:
<code class="language-csharp">static void Foo<T>() where T : new() { T t = new T(); Console.WriteLine(t.ToString()); // Works fine Console.WriteLine(t.GetHashCode()); // Works fine Console.WriteLine(t.Equals(t)); // Works fine // This throws a NullReferenceException... Console.WriteLine(t.GetType()); }</code>
當T
為Nullable<T>
(例如int?
)時,調用NullReferenceException
時會出現GetType()
。 這是因為 Nullable<T>
會覆蓋大多數方法,但 GetType()
不會。 調用非覆蓋 GetType()
期間的裝箱過程會產生空值。
代理屬性和 new()
約束:違背期望
Ayende Rahien 強調了一個類似但更複雜的場景:
<code class="language-csharp">private static void Main() { CanThisHappen<MyFunnyType>(); } public static void CanThisHappen<T>() where T : class, new() { var instance = new T(); // new() on a ref-type; should be non-null, then Debug.Assert(instance != null, "How did we break the CLR?"); }</code>
令人驚訝的是,這段代碼可能會使斷言失敗。通過使用攔截 MyFunnyProxyAttribute
調用並返回 new()
的代理屬性(如 null
),可能會違反斷言。這演示了運行時行為和自定義屬性之間可能發生意外交互。 這些示例強調了徹底測試和深入了解 CLR 內部工作原理的重要性,以避免 C# 和 .NET 開發中出現意外陷阱。
以上是C#和.NET中存在哪些意外行為和角案件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!