Monday, May 21, 2018

C# : Ternary operator "?:"

C# includes a special type of decision making operator '?:' called the ternary operator.
Syntax:
var result = Boolean conditional expression ? first statement : second statement
As you can see in the above syntax, ternary operator includes three parts. First part (before ?) includes conditional expression that returns boolean value true or false. Second part (after ? and before :) contains a statement which will be returned if the conditional expression in the first part evalutes to true. The third part includes another statement which will be returned if the conditional expression returns false.
Note :Ternary operator returns a value or expression included in the second or third part of it. It does not execute the statements.
Consider the following example where conditional expression x > y returns false, so it the returns the first statement after ?.
Example: Ternary operator

int x = 20, y = 10;

var result = x > y ? "x is greater than y" : "x is less than or equal to y";

Console.WriteLine(result);

output:
x is greater than y
The ternary operator can return a value of any data type. So it is advisable to store it in implicitly typed variable - var.
For example, it can return an integer value as shown below.
Example: Ternary operator

int x = 20, y = 10;

var result = x > y ? x : y;

Console.WriteLine(result);

output:
20
Ternary operator can also be used instead of if-else statement. The above example can be written using if-else statement as shown below.
Example: Ternary operator replaces if statement
    
int x = 20, y = 10;
int result = 0;

if (x > y)
    result = x;
else if (x < y)
    result = y;

Console.WriteLine(result);

output:
20

Nested Ternary operator:

Nested ternary operators are possible by including conditional expression as a second (after ?) or third part (after :) of the ternary operator..Consider the following example.
Example: Nested ternary operator

int x = 2, y = 10;

string result = x > y ? "x is greater than y" : x < y ? 
                                            "x is less than y" : x == y ? 
                                                        "x is equal to y" : "No result";

The ternary operator is right-associative. The expression a ? b : c ? d : e is evaluated as a ? b : (c ? d : e), not as (a ? b : c) ? d : e.

Points to Remember :

  1. Ternary operator: boolean expression ? first statement : second statement;
  2. Ternary operator returns a value, it does not execute it.
  3. It can be used to replace a short if-else statement.
  4. A nested ternary operator is allowed. It will be evaluted from right to left.

Sunday, May 20, 2018

C# : Generic Collection : Dictionary

Dictionary in C# is same as English dictionary. English dictionary is a collection of words and their definitions, often listed alphabetically in one or more specific languages. In the same way, the Dictionary in C# is a collection of Keys and Values, where key is like word and value is like definition.
Every class includes System.Collection.Generics namespace by default while creating a new class in visual studio.
Dictionary<TKey, TValue> is a generic collection included in the System.Collection.Generics namespace. TKey denotes the type of key and TValue is the type of TValue.

Dictionary Initialization:

A Dictionary can be initialized with a variable of IDictionary<Tkey, TValue> interface as well as with a Dictionary<TKey, Tvalue> class:
Example: Dictionary Initialization

IDictionary<int, string> dict = new Dictionary<int, string>();
        
//or

Dictionary<int, string> dict = new Dictionary<int, string>();

In the above example, we have specified types of key and value while declaring a dictionary object. An int is a type of key and string is a type of value that will be stored into a dictionary object named dict. You can use any valid C# data type for keys and values.
It is recommended to program to the interface rather than to the class. So, use IDictionary<TKey, TValue> type variable to initialize a dictionary object.
Note :Dictionary cannot include duplicate or null keys, where as values can be duplicated or set as null. Keys must be unique otherwise it will throw a runtime exception.

Important Properties and Methods of IDictionary<TKey, TValue>:

PropertyDescription
CountGets the total number of elements exists in the Dictionary<TKey,TValue>.
IsReadOnlyReturns a boolean indicating whether the Dictionary<TKey,TValue> is read-only.
ItemGets or sets the element with the specified key in the Dictionary<TKey,TValue>.
KeysReturns collection of keys of Dictionary<TKey,TValue>.
ValuesReturns collection of values in Dictionary<TKey,TValue>.
MethodDescription
void Add(T)Adds an item to the Dictionary collection.
void Add(TKey key, TValue value)Add key-value pairs in Dictionary<TKey, TValue> collection.
void Remove(T item)Removes the first occurance of specified item from the Dictionary<TKey, TValue>.
void Remove(TKey)Removes the element with the specified key.
bool ContainsKey(TKey key)Checks whether the specified key exists in Dictionary<TKey, TValue>.
bool ContainsValue(TValue value)Checks whether the specified key exists in Dictionary<TKey, TValue>.
void Clear()Removes all the elements from Dictionary<TKey, TValue>.
bool TryGetValue(TKey key, out TValue value)Returns true and assigns the value with specified key, if key does not exists then return false.

Add Elements into Dictionary:

Use Add() method to add the key-value pair in dictionary.
Add() Signature: void Add(TKey, Tvalue)
Example: Add elements in dictionary

IDictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");

Check whether a dictionary already stores specified key before adding a key-value pair.
The IDictionary type instance has one more overload for the Add() method. It accepts a KeyValuePair<TKey, TValue> struct as a parameter.
Add() Signature:void Add(KeyValuePair<TKey,TValue> item);
Example: Add key-value pair in dictionary

IDictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(new KeyValuePair<int, string>(1, "One"));
dict.Add(new KeyValuePair<int, string>(2, "Two"));

//The following is also valid
dict.Add(3, "Three");

It can also be initialized using collecton initializer syntax with keys and values as shown below.
Example: Dictionary Initialization using object initializer syntax

IDictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };

Access Dictionary Elements:

Dictionary elements can be accessed by many ways e.g. foreach, for loop or indexer.
Use foreach or for loop to iterate access all the elements of dictionary. The dictionary stores key-value pairs. So you can use a KeyValuePair<TKey, TValue> type or an implicitly typed variable var in foreach loop as shown below.
Example: Access elements using foreach

Dictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };

foreach (KeyValuePair<int, string> item in dict)
{
    Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
Output:
Key: 1, Value: One 
Key: 2, Value: Two 
Key: 3, Value: Three

Use for loop to access all the elements. Use Count property of dictionary to get the total number of elements in the dictionary.
Example: Access elements using for loop

Dictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };


for (int i = 0; i < dict.Count; i++)
{
    Console.WriteLine("Key: {0}, Value: {1}", 
                                            dict.Keys.ElementAt(i), 
                                            dict[ dict.Keys.ElementAt(i)]);
}

Output:
Key: 1, Value: One 
Key: 2, Value: Two
Key: 3, Value: Three

Dictionary can be used like an array to access its individual elements. Specify key (not index) to get a value from a dictionary using indexer like an array.
Example: Access Individual Element

Dictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };

Console.WriteLine(dict[1]); //returns One
Console.WriteLine(dict[2]); // returns Two

Output:
One 
Two

Note :Indexer takes the key as a parameter. If the specified key does not exist then a KeyNotFoundException will be thrown.
If you are not sure about the key then use the TryGetValue() method. The TryGetValue() method will return false if it could not found keys instead of throwing an exception.
TryGetValue() Signature: bool TryGetValue(TKey key, out TValue value)
Example: TryGetValue()

Dictionary<int, string> dict = new Dictionary<int, string>()
                                {
                                    {1,"One"},
                                    {2, "Two"},
                                    {3,"Three"}
                                };

string result;

if(dict.TryGetValue(4, out result))
{
    Console.WriteLine(result);
}
else
{
    Console.WriteLine("Could not find the specified key.");
}
Output:
Could not find the specified key.

Check for existing elements:

Dictionary includes various methods to determine whether a dictionary contains specified elements or keys. Use the ContainsKey() method to check whether a specified key exists in the dictionary or not.
Use the Contains() method to check whether a specified Key and Value pair exists in the dictionary or not.
ContainsKey() Signature: bool ContainsKey(TKey key)
Contains() signature: bool Contains(KeyValuePair<TKey, TValue> item)
Example: ContainsKey() & Contains()

Dictionary<int, string> dict = new Dictionary<int, string>()
                                            {
                                                {1,"One"},
                                                {2, "Two"},
                                                {3,"Three"}
                                            };
dict.ContainsKey(1); // returns true
dict.ContainsKey(4); // returns false

dict.Contains(new KeyValuePair<int,string>(1,"One")); // returns true

Another overload of the Contains() method takes IEqualityComperer as a second parameter. An instance of IEqualityComparer is used when you want to customize the equality comparison. For example, consider the following example of a dictionary that stores a Student objects.
Example: Custom comparer with Dictionary

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
}

class StudentDictionaryComparer : IEqualityComparer<KeyValuePair<int,Student>>
{
    public bool Equals(KeyValuePair<int, Student> x, KeyValuePair<int, Student> y)
    {
        if (x.Key == y.Key && (x.Value.StudentID == y.Value.StudentID) && (x.Value.StudentName == y.Value.StudentName))
            return true;

        return false;
    }

    public int GetHashCode(KeyValuePair<int, Student> obj)
    {
        return obj.Key.GetHashCode();
    }
}

class Program
{

    static void Main(string[] args)
    {
        IDictionary<int, Student> studentDict = new Dictionary<int, Student>()
                    {
                        { 1, new Student(){ StudentID =1, StudentName = "Bill"}},
                        { 2, new Student(){ StudentID =2, StudentName = "Steve"}},
                        { 3, new Student(){ StudentID =3, StudentName = "Ram"}}
                    };

        Student std = new Student(){ StudentID = 1, StudentName = "Bill"};

        KeyValuePair<int, Student> elementToFind = new KeyValuePair<int, Student>(1, std);

        bool result = studentDict.Contains(elementToFind, new StudentDictionaryComparer()); // returns true
    
        Console.WriteLine(result);
    }
}

Output:
true
In the above example, we have used StudentDictionaryComparer which derives IEqualityComparer to compare Student objects in the dictionary. The default comparer will only work with primitive data types.

Remove Elements in Dictionary:

Use the Remove() method to remove an existing item from the dictionary. Remove() has two overloads, one overload method accepts a key and the other overload method accepts a KeyValuePair<> as a parameter.
Remove() signature:
  • bool Remove(TKey key)
  • bool Remove(KeyValuePair<TKey,TValue>)
Example: Remove elements from Dictionary

Dictionary<int, string> dict = new Dictionary<int, string>()
                                            {
                                                {1,"One"},
                                                {2, "Two"},
                                                {3,"Three"}
                                            };

dict.Remove(1); // removes the item which has 1 as a key

Both Key and Value must match to remove an item. The item will not be removed if both are not matched. For example, the following example will not remove any item:

// removes nothing because value One1 is not matching
dict.Remove(new KeyValuePair<int, string>(2, "Two1")); 

Points to Remember :

  1. A Dictionary stores Key-Value pairs where the key must be unique.
  2. Before adding a KeyValuePair into a dictionary, check that the key does not exist using the ContainsKey() method.
  3. Use the TryGetValue() method to get the value of a key to avoid possible runtime exceptions.
  4. Use a foreach or for loop to iterate a dictionary.
  5. Use dictionary indexer to access individual item.
  6. Use custom class that derives IEqualityComparer to compare object of custom class with Contains() method.