Types
C# has two kinds of types: value types and reference types. But all types, including int, inherit from object.
-
Value types
Value types: primitive types, enum, struct, and nullable.
1). sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal (128bit high-percision decimal), bool. (Java only has signed numbers)
2). struct: Java does not have struct, this struct is similar to C/C++ struct
3). Each type except null, e.g. int, string, has a nullable type e.g. int?, string?. The nullable type's value can be a normal value or null. -
Reference types
reference types: Class, Interface, Array, and Delegate.
Delegate (function pointer): delegate type represents references to methods with a particular parameter list and return type.
Primitive types, null and array are provided by C#, developers can use them but not define them.
Enum, struct, class interface and delegate are definable.
class, struct, interface, delegate support generics. -
Box/Unbox
int i = 123; object o = i; // Boxing: allocate a space from heap, copy the value type's value into the reference type's space. int j = (int)o; // Unboxing: check if the box has the related value type; then copy the data out of the box into the value variable (on stack)
-
var
var is used to define a variable only within a method scope. var defined variable has implicit type that provides by compiler. And this implicit type can already be defined e.g. string, it can also be some types that are not defined yet.
Support: C# 3.0 and later
static void Main(string[] args) { var message = "Hello World!"; Console.WriteLine(message); Console.WriteLine(message.GetType()); // System.String var person = new { // var receive an anonymous class. name = "Nan Qin", desc = "A nice person." }; Console.WriteLine(person.GetType()); // <>f__AnonymousType0`2[System.String,System.String] // .name and .desc properties are read-only }
-
Nullable Type
C# value type's variables cannot be set to null. e.g. int, enum, struct ... If we declare a variable of value type without initializing a value, it will be set to its default value. However, C# provides a way to make these non-nullable value type variable nullable.
// int year = null; // Cannot convert null to 'int' because it is a non-nullable value type. int? year = null;
With a question mark, now it become nullable, which means it can be set to null. Reference type is naturally "nullable", so the question mark cannot be used with reference type. However, reference type cannot be called nullable type, nuallable type are defined as value type with null.
The ? is acutally implemented as a System.Nullable<T> generic.
System.Nullable<int> year = 10; // int + null => int? int year = 2019; int? year2 = null; // year = year2 ; nullable type can be assigned to a non-nullable type. bool same = (year == year2); // comparison is allowed.
Null conditional operator ?. (Elvis operator)
?. can form a chain, if any value is null, the evaluation of the expression is ended and return null.?. primarily used with reference type, nullable type does not need to have ?.
// nullable type does not need to have ?. int? year = null; string month = null; string str = year?.ToString(); str = year.ToString(); str = month?.ToString(); str = month.ToString(); // error.
Null-coalescing operator ??
variable = expression/variable ?? expression/variable/value. If the lefthand-side is null, then return the righthand-side. So it does not make sense if the lefthand-side is a immediate value or a non-nullable type.
The lefthand side of ?? can be nullable and reference type. Depending on the variable type, the righthand side may be OK to be nullable.
string text = "message"; int length = text?.Length ?? 0; // righthand side cannot be null since int cannot be null. int? length2 = text?.Length ?? null; // righthand side be null since int? can be null.
a ?? b ?? c === a ?? (b ?? c)