C# – Conversions

Conversions

A conversion always creates a new value from an existing one. Conversions can be either implicit or explicit.
Implicit conversions happen automatically, and explicit conversions require a cast.
For Implicit the compiler guarantee that it will succeed and no information is lost whereas explicit it is the opposite.

C# – Instance and Static

Instance and Static

Instance members

  • Data and function members that operate on the instance eg ints ToString() is a instance member of Integer class
  • By default members in a type/class are instance members

Static Members

  • Don’t operate on the instance of the type
  • Operate on the type itself

Example

using System;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Panda p1 = new Panda ("Pan Dee");
            Panda p2 = new Panda ("Pan Dah");
            
            Console.WriteLine(p1.Name);
            Console.WriteLine(p2.Name);
            Console.WriteLine(Panda.Population);
            

        }
    }
    
    public class Panda
    {
        //instance field
        public string Name;
        
        //static field
        //set to all Panda instances
        public static int Population;
        
        //Constructor
        public Panda (string n)
        {
            //Assign the instance field
            Name = n;
            
            //Increment the static Population field
            Population = Population + 1;
        }
    }
}

Static Class
– all its members must be static

C# – Constructors and Instantiation

Constructors and Instantiation

There are basically two types: Predefined types and Custom Type
Predefined types
It is the blueprint. It can be instantiated simply by using a literal such as 12 or “Hello world”. They are the types which are supported by the compiler. Examples such as int – represent a set of integers and perform arithmetic functions.

Custom Type
New operator creates instances of custom type. After instantiation the constructor is called to perform initialization.

Constructor
Defined like method but method name is the name of the class.

public class UnitConverter
{
	public UnitConverter (int unitRatio) { ratio = unitRatio;}
}

C# – Overview

Summary

  • Is an object oriented paradigm consists of encapsulation, inheritance and polymorphism
  • Unified Type system: all types share a common base type.
  • Classes and Interfaces: comprised of Classes and Interfaces
  • Properties, methods and events: properties – function members that encapsulate a piece of an objects state eg color, label text.
  • Functons can be treated as values: using delegates, functions can be passed as values
  • Supports pattern of purity: lambda expression, query expression and auto-properties for writing immutable types.

Type Safety

  • Supports static typing : enforces type safety at compile time rather than run time
  • Strongly typed language

Memory Management

  • Performs automatic memory management during run time
  • CLR has a garbage collector for reclaiming memory not being used

Platform Support

  • Allows cross platform support for Mac OS, iOS and Android.
  • ASP.NET 5 is the new framework which run either .NET Framework or .NET Core

The CLR and .NET Framework

  • Consists of CLR and set of libraries
  • CLR is the runtime for executign managed code
    Managed Code
    Packaged into assembly as .exe or .dll along metadata and type information
    Represented in intermediate language which laters gets converted into machine language.

C# – Other Operators

Other Operators

Most Common Operators
Equality and Comparison Operators

== : test for equality

!= : test for inequality

Conditional Operators:

&& : AND

|| : OR

Conditional operator (ternary operator)

Takes three operands q? a: b

The compound assignment operators are syntactic shortcuts that combine assignment
with another operator.
For example:

x *= 2 // equivalent to x = x * 2
x <<= 1 // equivalent to x = x << 1

Multiplicative Operators
x * y – multiplication.

x / y – division. If the operands are integers, the result is an integer truncated toward zero (for example, -7 / 2 is -3).

x % y – modulus. If the operands are integers, this returns the remainder of dividing x by y. If q = x / y and r = x % y, then x = q * y + r.
Additive Operators
x + y – addition for numeric and concatenation for string
x – y – subtraction for numeric

Shift Operators

x << y – shift bits left and fill with zero on the right.

x >> y – shift bits right. If the left operand is int or long, then left bits are filled with the sign bit. If the left operand is uint or ulong, then left bits are filled with zero.
Relational and Type-testing Operators

x < y – less than (true if x is less than y). x > y – greater than (true if x is greater than y).

x <= y – less than or equal to. x >= y – greater than or equal to.

is – type compatibility. Returns true if the evaluated left operand can be cast to the type specified in the right operand (a static type).

as – type conversion. Returns the left operand cast to the type specified by the right operand (a static type), but as returns null where (T)x would throw an exception.
Equality Operators

x == y – equality. By default, for reference types other than string, this returns reference equality (identity test). However, types can overload ==, so if your intent is to test identity, it is best to use the ReferenceEquals method on object.

x != y – not equal. See comment for ==. If a type overloads ==, then it must overload !=.

Logical AND Operator

x & y – logical or bitwise AND. Use with integer types and enum types is generally allowed.

Logical XOR Operator

x ^ y – logical or bitwise XOR. You can generally use this with integer types and enum types.

Logical OR Operator

x | y – logical or bitwise OR. Use with integer types and enum types is generally allowed.

Conditional AND Operator

x && y – logical AND. If the first operand is false, then C# does not evaluate the second operand.

Conditional OR Operator

x || y – logical OR. If the first operand is true, then C# does not evaluate the second operand.

Null-coalescing Operator

x ?? y – returns x if it is non-null; otherwise, returns y.

Conditional Operator

t ? x : y – if test t is true, then evaluate and return x; otherwise, evaluate and return y.

Assignment and Lambda Operators

x = y – assignment.

x += y – increment. Add the value of y to the value of x, store the result in x, and return the new value. If x designates an event, then y must be an appropriate function that C# adds as an event handler.

x -= y – decrement. Subtract the value of y from the value of x, store the result in x, and return the new value. If x designates an event, then y must be an appropriate function that C# removes as an event handler

x *= y – multiplication assignment. Multiply the value of y to the value of x, store the result in x, and return the new value.

x /= y – division assignment. Divide the value of x by the value of y, store the result in x, and return the new value.

x %= y – modulus assignment. Divide the value of x by the value of y, store the remainder in x, and return the new value.

x &= y – AND assignment. AND the value of y with the value of x, store the result in x, and return the new value.

x |= y – OR assignment. OR the value of y with the value of x, store the result in x, and return the new value.

x ^= y – XOR assignment. XOR the value of y with the value of x, store the result in x, and return the new value.

x <<= y – left-shift assignment. Shift the value of x left by y places, store the result in x, and return the new value. x >>= y – right-shift assignment. Shift the value of x right by y places, store the result in x, and return the new value.

=> – lambda declaration.

C# Unary Operators

Unary Operators

These operators have higher precedence than multiplicative operators and lower precedence than the primary operators.
+x
Functions as unary or binary as addition if it is numeric or concatenation if one of the value is string
-x
Performs numeric negation.
!x
Logical negation operator
~x
Bitwise complement.
await (Asynchronous method)
Awaits a Task. It iserts a sustension point to wait for a task to complete
&x – address of
Performs either unary or binary
*x – dereferencing
Works as a multiplication operator or dereference operator

C# Primary Operators

Operators

There are many different kinds of operators defined in C#. The operators can also be overloaded to change their meaning when applied to user-defined type.

Most common operators are (==, !=, <, >, &, |) and generally used with enumeration types.

Primary Operators

These are the highest precedence operators.
(Dot).Operator (x.y)

Composed of 2 primary expressions: member-lookup and method call. It is used for member access such as access specific method within the framework.

-- Accessing Console class in System namespace
System.Console.WriteLine("Hello World");

class Simple
{
	public int a;
	public void b() {}
}

--Initiate
Simple s = new Simple();

-- Accessing the members
s.a = 6; --asign to field a
s.b(); -- invoke member function b;

Null-conditional Operators (x?.y)
Returns null if the left-hand operand is null. It tests null before performing member access. In a chain conditional operation if operation returns null then rest execution stops. Null-conditional operator is useful when invoking delegates in a thread-safe with less code.

-- int? length - can be null or number
-- return null if customers is null or access the Length property
int? length = customers?.Length; 

-- return null if array is empty or access the array objects
Customer first = customer?[0]

-- return null if customers, first customer or Orders is null
int? count = customers?[0]?.Orders?.Count();

-- operations with lower precedence will continue to operate
A?.B?.C?[0] ?? E
A?.B?.C?[0] == E

-- using with thread
PropertyChanged?.Invoke(e);

Null-conditional Index Access (x?[y])

Returns null if the left-hand operand is null

Customer first = customers?[0];  -- null if customers is null 

Function Invocation f(x)
It is use to specify the order of operation. It cannot be overloaded.
1. Specifiy casts or type conversion

double x = 23.6;
int a;
a = (int)x;

2. Invoke methods or delegates
TestMethod();

Aggregate Object Indexing a[x]
Used for arrays, indexers and attributes or with pointers. Out of range exception if array is out of range.

int[] array;  -- array of int
array = new int[50] -- array for 50 element
--access array element
array[4];

Square brackets are also used to specify Attributes:

// using System.Diagnostics;
[Conditional("DEBUG")] 
void TraceMethod() {}

Postfix Increment (x++)

Returns the value of x by incrementing its operand by 1. It can appear before or after the variable.
prefix increment – result return after increment
postfix increment – result return before increment

double x = 2.5;
Console.WriteLine(++x); -- 3.5
x = 1.5;
Console.WriteLine(x++); -- 1.5
Console.WriteLine(x); -- 2.5

Postfix Decrement (x–)
Returns the decrement value by the operand. Can appear before or after the variable.

double x = 2.5;
Console.WriteLine(--x); -- 1.5
x = 1.5;
Console.WriteLine(x--); --1.5
Console.WriteLine(x); -- 0.5

Type Instantiation (new)
Create object and invoke constructors also create instances of anonymous types. It can be used to invoke the default constructor for value types. Cannot be overloaded. Remember not to declare default constructor for struct because every value type has a public constructor.

-- Class
Class1 obj = new Class1();

-- anonymous object
var query = from cust in customers  
            select new { Name = cust.Name, Address = cust.PrimaryAddress };  

-- value types
int i = new int();  

typeof()
Returns the System.Type object for a particular object. Can be used with open generics types.

System.Type type = typeof(int);  

For run-time expression

int i = 0;  
System.Type type = i.GetType(); 

int radius = 3;
        Console.WriteLine("Area = {0}", radius * radius * Math.PI);
        Console.WriteLine("The type is {0}",
                          (radius * radius * Math.PI).GetType()

-- generic example
string s = method.ReturnType.GetInterface  
    (typeof(System.Collections.Generic.IEnumerable<>).FullName);  


public class Program
    {
        public int sampleMember;
        public void SampleMethod() {}
        
        public static void Main(string[] args)
        {

        Type t = typeof(Program);
      // Alternatively, you could use
      // ExampleClass obj = new ExampleClass();
      // Type t = obj.GetType();

      Console.WriteLine("Methods:");
      System.Reflection.MethodInfo[] methodInfo = t.GetMethods();

      foreach (System.Reflection.MethodInfo mInfo in methodInfo)
         Console.WriteLine(mInfo.ToString());

      Console.WriteLine("Members:");
      System.Reflection.MemberInfo[] memberInfo = t.GetMembers();

      foreach (System.Reflection.MemberInfo mInfo in memberInfo)
         Console.WriteLine(mInfo.ToString());     
            
        
            
        }
        
 
    }

Checked
Enables overflow checking for integer operations and conversions

        int ten = 10;
        int i2 = 2147483647 + ten;
        Console.WriteLine(i2);
        Console.WriteLine(checked(2147483647 + ten));    
        
        checked
        {
            int i3 = 2147483647 + ten;
            Console.WriteLine(i3);
        } 

Unchecked
Disables overflow checking for integer operations. This is the default compiler behavior.

unchecked
{
    int1 = 2147483647 + 10;
}
int1 = unchecked(ConstantMax + 10);

Default Value Expression
Produces the default value of type T, null for references, 0 for numeric types.

var s = default(string);
var d = default(dynamic);
var i = default(int);
var n = default(int?); // n is a Nullable int where HasValue is false.

It can be applied in the following places:
– Variable initializer
– Variable assignment
– Declaring the default value for an optional parameter
– Providing the value for a method call argument
– Return statement (or expression in an expression bodied member)
Delegate (Anonymous Methods)
Declares and returns a delegate instance.

// Create a delegate.
delegate void Del(int x);

// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };

It is an error to have jump statements such as continue or break.
sizeof
Returns the size in bytes for an unmanaged type such as enum, pointer,user-defined structs.
-> Pointer
Pointer dereferencing combined with member access.Used in unsafe environment.

C# – Nullable Types

Nullable Types

Is a instance of the System.Nullable Struct

Value type cannot be assigned a null value eg int i = null, but with Nullable struct you can store null with value types. All reference types are nullable but value types are not.
Example
Nullable<int> intValue = 5 ?? null; — can have interger value or null
Nullable<bool> boolValue = true ?? null — can have true, false or null
Nullable<double> doubleVal = 2.14 ?? null — can have double or null
Nullable<char> charVal = ‘a’ ?? null — can have char or null
Nullable<int>[] arr = new Nullable<int>[10]

Shorthand syntax
‘?’

Nullable<int> i = null;
//becomes
int? i = null
//is a lightweight immutable structure.
public struct Nullable<T> where T : struct
{
	public bool HasVaalue { get; }

	public T Value { get; }

	//rest of the implementation
}

Attempting to retrieve Value when HasValue is false throws an InvalidOperationException.

Constructors
Nullable<T>(T) – initialize a new instance

Declaration

Nullable<int> i = null;

Properties
HasValue – boolean return whether Nullable object has valid value

int? val = null;
Console.WriteLine(val.HasValue); //false
             
val = 1;
Console.WriteLine(val.HasValue);//true

Alternative way of doing this will be using the operator:

int? y = 10;
if(y != null)
   Console.WriteLine("Has Value");

Value – gets the value of the current Nullable<T> object

Console.WriteLine(val.Value);//1
Console.WriteLine(val);// 1
if(val == 1)
     Console.WriteLine("True");

Methods
Equals(Object)
Indicates whether the current Nullable<T> object is equal to a specified object

int? nullInt1 = 100;
int? nullInt2 = 200;
object myObj;
            
if(nullInt1.Equals(nullInt2))
  {
       Console.WriteLine("Both are equal");
  }

GetHashCode()
Retrives the hash code of the object returned by the Value property

GetValueOrDefault()
Retrieves the value of the current Nullable<T> object or the default value.

static void Main(string[] args)
{
    Nullable i = null;

    Console.WriteLine(i.GetValueOrDefault()); 
}

GetValueOrDefault(T)
Retrieves the value of the current Nullable<T> object or the specified default value

ToString()
Returns the text representation of the value of the current Nullable<T> object.

 DateTime? dt2 = DateTime.Now;
 Console.WriteLine(dt2.HasValue ? dt2.Value.ToString("yyyy-MM-dd hh:mm:ss") : "[N/A]");

Conversions
Explicit(Nullable<T> to T)
Explicit conversion of a Nullable<T> instance to its underlying value.

int? n = null;

//int m1 = n;      // Will not compile.
int m2 = (int)n;   // Compiles, but will create an exception if n is null.
int m3 = n.Value;  // Compiles, but will create an exception if n is null.

Implicit(T to Nullable<T>)
Creates a new Nullable<T> object initialized to a specified value.

int? n1 = null;
int? n2;
n2 = 10;

Nullable Int eg int?
Can assigned any value from -2147483648 to 2147483647, or a null value. With null an int is invalid, missing or uninitialized, no special values are needed like -1. Aliased to System.Int32 type therefore System.Int32? will do the job.

DateTime Nullable
DateTime is a struct, you get DateTime object and not reference. Declaring int cannot be null so declaring DateTime cannot be null. Adding question mark turns into nullable type which means that it can be DateTime object or null. DateTime? is equivalent to Nullable

DateTime? a = null;
if(!a.HasValue)
{
	a = DateTime.Now;
	if(a.HasValue)
	{
	  Console.WriteLine(a.Value);
	}
}

Casting bool
bool? cannot be used with conditionals such as if, for or while, you will need to first check the HasValue property to ensure that its value is not null.

bool? test = null;
if(test ?? false)
{
     Console.WriteLine("Hello there");
}
           
if(!test.HasValue)
{
    Console.WriteLine("Does not HasValue");
}

Operators (operator lifting)

The Nullable<T> struct does not define basic operators but it lifts or borrows operators from value types.

The predefined unary and binary operators and any user-defined operators that exist for value types maybe also used by nullable types. The operators will produce null value if the operands are null.. For comparisons with nullable types, will evaluate to false except != operator.

 int? a = 10;
 int? b = null;
            
 a++;
 Console.WriteLine(a); -- 11
 a = a * 10;
 Console.WriteLine(a); -- 110
 a = a + b;
 Console.WriteLine(a); -- null

Use ?? operator to assign a nullable type to a non-nullable type

int? i = null;
int j = i ?? 0;
-- with multiple null types
int? e = null;
int? f = null;
int g = e ?? f ?? -1;

In the above example, i is a nullable int and if you assign it to the non-nullable int j then it will throw a runtime exception if i is null. So to mitigate the risk of an exception, we have used the ‘??’ operator to specify that if i is null then assign 0 to j.
You can also use the == and != operators with a nullable type, as shown in the following example: if (x != null) y = x;

Note: If exactly one operand is null, the operands are unequal and if both operands are non-null, their Values are compared.

int? x = 5;
int? y = 10;
{
	bool b = x < y;      // true
}
// The above line is equivalent to:
{
	bool b = (x.HasValue && y.HasValue) ? (x.Value < y.Value) : false;
}

Mixing nullable and non-nullable operators

You can mix and match nullable and non-nullable types due to implicit conversion.

int? a = null;
int b = 2;
int? c = a + b;   // c is null - equivalent to a + (int?)b

Bool? with & and | Operatos

// When supplied operands of type bool?, the & and | operators treat null as an unknown
// value, rather like with SQL:

bool? n = null;
bool? f = false;
bool? t = true;
Console.WriteLine (n | n);    // (null)
Console.WriteLine (n | f);    // (null)
Console.WriteLine (n | t);    // True
Console.WriteLine (n & n);    // (null)
Console.WriteLine (n & f);    // False
Console.WriteLine (n & t);    // (null)

Benefits
It is good to use when retrieving data from database tables where fields have nulls, you can define the class as:

public struct titleAuthor
{
	public string id;
	public string title;
	public int? royaltyper; -- can be null in database table
}

Assignment Rules
Nullable type declaration must assigned a value
Access the value using NullableType.value will throw runtime exception if nullable type is null or not assigned any value.

Nullable<int> i = null;
Console.WriteLine(i.Value);

Static Nullable Helper class
Comparison operators will not work against null

    int? i = null;
    int j = 10;


    if (i < j)
        Console.WriteLine("i < j");
    else if( i > 10)
        Console.WriteLine("i > j");
    else if( i == 10)
        Console.WriteLine("i == j");
    else
        Console.WriteLine("Could not compare");

Nullable static class is a helper class for Nullable types. It provides a compare method to compare nullable types. It also has a GetUnderlyingType method that returns the underlying type argument of nullable types.

    int? i = null;
    int j = 10;

    if (Nullable.Compare<int>(i, j) < 0)
        Console.WriteLine("i < j");
    else if (Nullable.Compare<int>(i, j) > 0)
        Console.WriteLine("i > j");
    else
        Console.WriteLine("i = j");

Boxing Nullable Types

When T? is boxed, the value stored on heap in T and not T?. Objects based on nullable types are only boxed if the object is non-null. If the object is non-null and hasValue is true then boxing will happen and also it can be unboxed into nullable types. C# also permits the unboxing of nullable types with the as operator

object o = "string";
int? x = o as int?;
Console.WriteLine (x.HasValue);   // False

How to Identify a Nullable Type
Using System.Reflection namesapce to generate Type objects that represent Nullable types.

System.Type type = typeof(int?);

It is impossible to get the type at runtime using the GetType() method because the boxing operation is performed during runtime therefore it will return the Type object that represents the type.

It is useful when you want to add another state invalid or uninitialized to a value type.

Nullable Types & Null Operators (Null Coalescing Operator)

Nullable types work particularly well with the ?? operator which is equivalent to GetValueOrDefault() method. It can be used with nullable types and also with reference types. It means that "If the operand is non-null, give the to me; otherwise, give me the default value."

int? x = null;
int y = x ?? 5;
Console.WriteLine (y);	// 5

int? a = null, b = 1, c = 2;
Console.WriteLine (a ?? b ?? c);  // 1 (first non-null value)

Nullable types also work well with the null-conditional operator

System.Text.StringBuilder sb = null;
int? length = sb?.ToString().Length;
length.Dump();

// We can combine this with the null coalescing operator to evaluate to zero instead of null:

int length2 = sb?.ToString().Length ?? 0;  // Evaluates to 0 if sb is null
length2.Dump();

A nullable type can also be used to represent the backing field called ambient property. Ambient property, if null returns the value of its parent.

// Color is an ambient property:
public class Row
{
  /*...*/
  Grid parent;
  Color? color;

  public Color Color
  {
	get { return color ?? parent.Color; }
	set { color = Color == parent.Color ? (Color?)null : value; }
  }
}

class Grid
{
	/*...*/
	public Color Color { get; set; }
}

void Main() { }

Learning about JSON

Learning about JSON

JSON JavaScript Object Notation is a lightweight format that is used for data interchanging. All modern browsers support JSON object. JSON objects are surrounded by curly brackets {} and its objects are written in key/value pairs where keys must be string data type and values must be one of the valid JSON data type such as string, number, object, array, boolean, null. Key and values are separated by semicolon.

Example

{
     "firstName": "JBC",
     "lastName": "Edge",
     "address": {
         "streetAddress": "43 2nd Street",
         "city": "New Zealand",
         "state": "NZ",
         "postalCode": 00064
     },
     "phoneNumbers": [
         "0215948563",
         "2928524136"
     ]
 }

JSON.stringify
Used to create a JSON string out of an object or array, it serializes a JavaScript object into a JSON string. It turns a Javascript object into JSON text and stores that JSON text in a string. In simple terms is to create a JSON string out of an object or array.

JSON.parse
Used for parsing data that was received as JSON, it deserializes a JSON string into a JavaScript object. Simply it turns a string of JSON text into a JavaScript object

NOTE
In javascript JSON is a string. Not all Javascripts objects are JSON and vice versa.
Example:

var x = {x:y} 

This is Javascript object and NOT JSON

var x = '{"x":"y"}';

This is JSON and NOT Javascrpt object
To convert JSON string into Javascript object you need JSON.parse() function

var x = JSON.parse('{"x":"y"}');

Example

const myObj = {
  name: 'Test',
  age: 2,
  city: 'nandi'
};

const myObjStr = JSON.stringify(myObj);

console.log(myObjStr);
// "{"name":"Test","age":2,"city":"nandi"}"

console.log(JSON.parse(myObjStr));
// Object {name: "Test", age: 2, city: "nandi"}

var myObject = JSON.parse(myObjStr);

console.log(myObject.city);
//nandi

With Arrays

const myArr = ['carrot', 'spinach', 'tomatoes'];

//JSON string
const myArrStr = JSON.stringify(myArr);

console.log(myArrStr);
// "["carrot","spinach","tomatoes"]"
//JavaScript object
console.log(JSON.parse(myArrStr));
// ["carrot","spinach","tomatoes"]

var myObject = JSON.parse(myArrStr);

console.log(myObject[0]);
//carrot

With Second Argument
JSON.parse()
Can pass second argument as a reviver function to transform object values before they are returned.

const user = {
  name: 'JBC',
  email: '[email protected]',
};

const userStr = JSON.stringify(user);

JSON.parse(userStr, (key, value) => {
  if (typeof value === 'string') {
    return value.toUpperCase();
  }
  return value;
});

JSON.stringify()
Can take two additional arguments first one as replacer function and second as string or number value to use as the returned string.
Replacer function can be used as filtered-out values

const user = {
  id: 12,
  name: 'JBC',
  email: '[email protected]'
};

function replacer(key, value) {
  console.log(typeof value);
  if (key === 'email') {
    return undefined;
  }
  return value;
}


const userStr = JSON.stringify(user, replacer);

Adding more characters/strings

const userStr1 = JSON.stringify(user, null, '=>');

console.log(userStr1);

Read more here