I don't understand how the C# compiler is assigning
var min = int.MinValue;
uint works = (uint)(min < 0 ? -min : min);
uint worksUnchecked = unchecked((uint)-int.MinValue);
This doesn't really have anything to do with the ternary operator per se. Rather, it's because in the context of the ternary operator, you are casting variable values at runtime, while in the context of the
uintMin2, you are casting a literal at compile-time.
And the reason this matters is that the default
unchecked context is different at compile time than it is at runtime.
From the documentation:
By default, an expression that contains only constant values causes a compiler error if the expression produces a value that is outside the range of the destination type. If the expression contains one or more non-constant values, the compiler does not detect the overflow
Which is another way of saying that, by default, if the compiler can determine that an expression is out-of-range, it will generate an error. If it can't (within the rules of the language specification…that it theoretically could by actually tracing the execution of the code at compile-time would be irrelevant), then it won't.
These defaults can be changed, of course. As you've already seen, you can apply
unchecked to force the compiler to ignore errors at compile-time. You can also use the
/checked compiler switch to control what happens at compile-time.