Q:

Why does this implicit conversion from int to uint work?

Using Casting null doesn't compile as inspiration, and from Eric Lippert's comment:

That demonstrates an interesting case. "uint x = (int)0;" would
  succeed even though int is not implicitly convertible to uint.

We know this doesn't work, because object can't be assigned to string:
string x = (object)null;

But this does, although intuitively it shouldn't:
uint x = (int)0;

Why does the compiler allow this case, when int isn't implicitly convertible to uint?

A:

Integer constant conversions are treated as very special by the C# language; here's section 6.1.9 of the specification:

A constant expression of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type. A constant expression of type long can be converted to type ulong, provided the value of the constant expression is not negative.

This permits you to do things like:
byte x = 64;

which would otherwise require an ugly explicit conversion:
byte x = (byte)64; // gross

A:

The following code wil fail with the message "Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)"
int y = 0;
uint x = (int)y;

And this will fail with: "Constant value '-1' cannot be converted to a 'uint'"
uint x = (int)-1;

So the only reason uint x = (int)0; works is because the compiler sees that 0 (or any other value > 0) is a compile time constant that can be converted into a uint

