You're absolutely correct to be confused at first glance! In general, you can't directly compare int? and int because the result would be a bool?, which is not a legal if statement. Yet your code is working because of the internal treatment of nullable comparison by the C# compiler.
Why Does It Work? When you do:
if (v > 0) the compiler will not just directly compare v and 0. Instead, it rewrites the expression to:
if (v.HasValue && v.Value > 0) So if v is null, then v.HasValue is false, and the whole thing short-circuits to false, which is perfectly fine in an if statement.
What About Other Cases? If you tried to do something like this:
bool result = v > 0; it would not compile, because v > 0 returns a bool?, which can't be assigned directly to bool without an explicit cast.