Sunday, November 12, 2017

Nullable in C#

Nullable is a special generic class meant to enable value types to be set to null.

Nullable<bool> nullableOfBool = false;
Nullable<int> nullableOfInt = 0;
Nullable<float> nullableOfFloat = 0.0f;

bool? nullableOfBool = false;
int? nullableOfInt = 0;
float? nullableOfFloat = 0.0f;

As you can see you can initialize them like if they were value types. Moreover, you can treat them like value types as long as you don't mix them with actual value types:

int? v1 = 1;
int? v2 = 7;
int? result = v1 + v2;

If for some reason you wanna access underlying type, you can do this by accessing Value property of Nullable:

int v1 = 1;
int? v2 = 7;
int result = v1 + v2.Value;

Or simply cast it to a corresponding value type:

int v1 = 1;
int? v2 = 7;
int result = v1 + (int)v2;

If you don't know if your nullable contains any value, use can check it using HasValue property.

Null-conditional operator in C#

Null-conditional operator is a new .NET feature meant to ease your life as a developer. Its primary purpose is NullReferenceException prevention. I'mma give you an example:

namespace ConsoleApp
{
    class Car
    {
        public string Brand { get; set; }
    }

    class Program
    {
        static void DoSomethingWithCar(Car car)
        {
            // This is where you omitted check for null.
            string brand = car.Brand; // And this is where you get into trouble.
        }
        static void Main(string[] args)
        {
            DoSomethingWithCar(null);
        }
    }
}

Now we can either add missing check or use null-conditional operator:

namespace ConsoleApp
{
    class Car
    {
        public string Brand { get; set; }
    }

    class Program
    {
        static void DoSomethingWithCar(Car car)
        {
            // Null-conditional operator checks if car is null and if it is,
            // prevents us from accessing Brand property and sets brand to null.
            string brand = car?.Brand;
        }
        static void Main(string[] args)
        {
            DoSomethingWithCar(null);
        }
    }
}

Let's slightly modify our example so you can see another use case of null-conditional operator:

namespace ConsoleApp
{
    class Car
    {
        public string Brand { get; set; }
    }

    class Program
    {
        static void DoSomethingWithCars(Car[] cars)
        {
            // Null-conditional operator checks if cars array is null and if it is,
            // prevents us from accessing its first element and returns null.
            Car car = cars?[0];
        }
        static void Main(string[] args)
        {
            DoSomethingWithCars(null);
        }
    }
}

As you can see null-conditional operator can be used with both dot operator and subscript operator (square brackets).

Default values in C#

Here is the thing, C# doesn't allow you to leave a variable unitialized. What I mean is that every time you create a variable it's automatically assigned some sorta default value.

Integral types:
sbyte 0
byte 0
short 0
ushort 0
int 0
uint 0
long 0l
ulong 0ul

Floating-point types:
float 0.0f
double 0.0d
decimal 0.0m

Boolean:
bool false

Any class, struct, including these two:
object null
string null

Enumerations:
enum 0 (value of the first enumerator)

Characters:
char '\0'