What's the strangest corner case you've seen in C# or .NET?
I think I showed you this one before, but I like the fun here - this took some debugging to track down! (the original code was obviously more complex and subtle...)
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
// so it looks like an object and smells like an object...
// but this throws a NullReferenceException...
Console.WriteLine(t.GetType());
}
So what was T...
Answer: any Nullable<T>
- such as int?
. All the methods are overridden, except GetType() which can't be; so it is cast (boxed) to object (and hence to null) to call object.GetType()... which calls on null ;-p
Update: the plot thickens... Ayende Rahien threw down a similar challenge on his blog, but with a where T : class, new()
:
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?");
}
But it can be defeated! Using the same indirection used by things like remoting; warning - the following is pure evil:
class MyFunnyProxyAttribute : ProxyAttribute {
public override MarshalByRefObject CreateInstance(Type serverType) {
return null;
}
}
[MyFunnyProxy]
class MyFunnyType : ContextBoundObject { }
With this in place, the new()
call is redirected to the proxy (MyFunnyProxyAttribute
), which returns null
. Now go and wash your eyes!
What is the worst gotcha in C# or .NET?
private int myVar;
public int MyVar
{
get { return MyVar; }
}
Blammo. Your app crashes with no stack trace. Happens all the time.
(Notice capital MyVar
instead of lowercase myVar
in the getter.)
Object.ReferenceEquals prints true for two different objects
This happens because special case is made for constructing empty strings from empty char arrays. The string constructor returns string.Empty
for empty strings constructed in this way:
string x = new string(new char[0]);
string y = new string(new char[0]);
Console.WriteLine(object.ReferenceEquals(x, y)); // true
Console.WriteLine(object.ReferenceEquals(x, string.Empty)); // true
From the reference source for string (this is the constructor for a char*
parameter):
[System.Security.SecurityCritical] // auto-generated
private unsafe String CtorCharPtr(char *ptr)
{
if (ptr == null)
return String.Empty;
#if !FEATURE_PAL
if (ptr < (char*)64000)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeStringPtrNotAtom"));
#endif // FEATURE_PAL
Contract.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
try {
int count = wcslen(ptr);
if (count == 0)
return String.Empty;
String result = FastAllocateString(count);
fixed (char *dest = result)
wstrcpy(dest, ptr, count);
return result;
}
catch (NullReferenceException) {
throw new ArgumentOutOfRangeException("ptr", Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
}
}
And also (this is the constructor for a char[]
parameter):
[System.Security.SecuritySafeCritical] // auto-generated
private String CtorCharArray(char [] value)
{
if (value != null && value.Length != 0) {
String result = FastAllocateString(value.Length);
unsafe {
fixed (char * dest = result, source = value) {
wstrcpy(dest, source, value.Length);
}
}
return result;
}
else
return String.Empty;
}
Note the lines:
if (count == 0)
return String.Empty;
and
else
return String.Empty;
Related Topics
How to Apply an Xslt Stylesheet in C#
Why Must "Stride" in the System.Drawing.Bitmap Constructor Be a Multiple of 4
How to Exclude Property from Json Serialization
Why Response.Redirect Causes System.Threading.Threadabortexception
Distinct Not Working With Linq to Objects
Reading Settings from App.Config or Web.Config in .Net
How to Delete an Element from an Array in C#
Build and Load Assetbundles in Unity
Get the Correct Week Number of a Given Date
Odbcconnection Returning Chinese Characters as ""
Convert Datatable to Json in C#
Why Does the Ef 6 Tutorial Use Asynchronous Calls
Linq-To-Entities Join VS Groupjoin