C# and .NET: Unveiling Hidden Surprises
Software development often reveals unexpected behaviors. C# and .NET, while powerful, are no exception. This article explores some intriguing corner cases that can challenge even experienced developers.
String Creation: A Counterintuitive Result
Consider this seemingly simple code snippet:
string x = new string(new char[0]); string y = new string(new char[0]); Console.WriteLine(object.ReferenceEquals(x, y));
The output is True
, contradicting the expectation that new
creates distinct objects for reference types. The Common Language Runtime (CLR) optimizes this specific scenario, reusing the same empty string instance.
Generic Types and Nullable<T>: A NullReferenceException Mystery
The following code demonstrates another unexpected behavior:
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()); }
When T
is Nullable<T>
(e.g., int?
), a NullReferenceException
occurs when calling GetType()
. This is because Nullable<T>
overrides most methods, but not GetType()
. The boxing process during the call to the non-overridden GetType()
results in a null value.
Proxy Attributes and the new()
Constraint: Defying Expectations
Ayende Rahien highlighted a similar, yet more sophisticated, scenario:
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?"); }
This code, surprisingly, can fail the assertion. By using a proxy attribute (like MyFunnyProxyAttribute
) that intercepts the new()
call and returns null
, the assertion can be violated. This demonstrates the potential for unexpected interactions between runtime behavior and custom attributes. These examples highlight the importance of thorough testing and a deep understanding of the CLR's inner workings to avoid unexpected pitfalls in C# and .NET development.
The above is the detailed content of What Unexpected Behaviors and Corner Cases Exist in C# and .NET?. For more information, please follow other related articles on the PHP Chinese website!