C# supports strongly typed implicit variable declarations with the keyword
var, and implicitly typed arrays with the keyword
new followed by a collection initializer.
C# supports a strict Boolean data type,
bool. Statements that take conditions, such as
if, require an expression of a type that implements the
true operator, such as the Boolean type. While C++ also has a Boolean type, it can be freely converted to and from integers, and expressions such as
if(a) require only that
a is convertible to bool, allowing
a to be an int, or a pointer. C# disallows this "integer meaning true or false" approach, on the grounds that forcing programmers to use expressions that return exactly
bool can prevent certain types of programming mistakes such as
if (a = b) (use of assignment
= instead of equality
==, which while not an error in C or C++, will be caught by the compiler anyway).
C# is more type safe than C++. The only implicit conversions by default are those that are considered safe, such as widening of integers. This is enforced at compile-time, during JIT, and, in some cases, at runtime. No implicit conversions occur between Booleans and integers, nor between enumeration members and integers (except for literal 0, which can be implicitly converted to any enumerated type). Any user-defined conversion must be explicitly marked as explicit or implicit, unlike C++ copy constructors and conversion operators, which are both implicit by default.
C# has explicit support for covariance and contravariance in generic types, unlike C++ which has some degree of support for contravariance simply through the semantics of return types on virtual methods.
The C# language does not allow for global variables or functions. All methods and members must be declared within classes. Static members of public classes can substitute for global variables and functions.
Local variables cannot shadow variables of the enclosing block, unlike C and C++.