Thursday, May 26, 2016

Indexers in C#

In today's blog post, we will understand the indexers in C#. Indexers are a useful and less-known feature of C#.

Indexers in C#

An indexer is a way to overload the indexing operator (just like we access array's elements). By defining an indexer on a class, we can access it's properties using an index. Let's take a look at an example to understand how it's done.




Indexers in C#


Suppose we have a Vector class like this:

public class Vector
{
    public int X { get; set; }
    public int Y { get; set; }

    public int this[int index]
    {
        get
        {
            switch (index)
           {
                 case 0: return X;
                 case 1: return Y;
                 default: throw new IndexOutOfRangeException();
           }
        }

        set
        {
            switch (index)
            {
                case 0: X = value;
                    break;
                case 1: Y = value;
                    break;
                default: throw new IndexOutOfRangeException();
            }
        }

    }

}

So here we defined integer indexer in the class. Please note the syntax how we used the "this" keyword with "int index" parameter. Inside the method definition we have the get and set, so we can get the property as well as set the property using integer index.

We are not just limited to integer index. We can even have string indexer like this:


public int this[string index]
{
     get
     {
        switch (index)
        {
              case "x": return X;
              case "X": return X;
              case "y": return Y;
              case "Y": return Y;
              default: throw new IndexOutOfRangeException();
        }

     }

     set
     {
          switch (index)
          {
              case "x":
              case "X":
                  X = value;
                  break;
              case "y":
              case "Y":
                   Y = value;
                   break;
              default: throw new IndexOutOfRangeException();
          }
     }

Please note the "string index" parameter this time. Inside it we define what to do in case of "x" or "X" and "y" or "Y".
Now, let's take a look at how we can use these integer as well as string indexers:

static void Main(string[] args)
{
      var vector1 = new Vector();
      vector1[0] = 2; // integer indexer
      vector1[1] = 3;

      //string indexer
      Console.WriteLine("Vector 1: X = {0}, Y = {1}",
                   vector1["X"], vector1["Y"]);
      Console.ReadLine();
}

So we saw how they can add to readability of the code. Using indexers, we can access each of the property like we are accessing the array elements.

Conclusion

So we saw how to define integer as well as string indexers on a class. Just because we can define indexers doesn't mean it's always the right solution. If it increases the readability of the code and makes sense then only we should use them. In our example, for Vector class it makes it easy to read the code.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)


Thursday, May 19, 2016

Operator Overloading in C#

In today's post, I will be discussing operator overloading in C# with an example.

Operator Overloading

In general, operators like "+", "-", etc have pre-defined functionalities. They can be used for mathematical operations for add, subtract, etc. Using operator overloading, we can have our own implementations for operations where one or both the operands are of a user defined class or struct type.

Operator Overloading in C#



Many operators can be overloaded and some of the operators cannot be overloaded. And some of the operators can be overloaded only in pairs. Here is the table from MSDN that shows the complete list of operators that can be overloaded.


OperatorsOverloadability
+, -, !, ~, ++, --, true, false
These unary operators can be overloaded.
+, -, *, /, %, &, |, ^, <<, >>
These binary operators can be overloaded.
==, !=, <, >, <=, >=
The comparison operators can be overloaded. However, they can be overloaded only in corresponding pairs.
&&, ||
The conditional logical operators cannot be overloaded, but they are evaluated using & and |, which can be overloaded.
[]
The array indexing operator cannot be overloaded, but you can define indexers.
(T)x
The cast operator cannot be overloaded, but you can define new conversion operators.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=,>>=
Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded.
=, ., ?:, ??, ->, =>, f(x), as, checked,unchecked, default, delegate, is, new,sizeof, typeof
These operators cannot be overloaded.

Let's take a look at an example of how operator overloading is done. Suppose, we have a Vector class and we want to overload the "+" operator. In order to overload any operator, we need to use "static" keyword and "operator" keyword like this:

public class Vector
{
    public int X { get; set; }
    public int Y { get; set; }

    public static Vector operator +(Vector A, Vector B)
    {
       return new Vector() 
        { X = A.X + B.X, Y = A.Y + B.Y };
    }

}

So now we can simply use "+" operator to add two vectors. So when we add two vectors, it adds their corresponding X and Y values and returns the new vector.

static void Main(string[] args)

{
       var vector1 = new Vector() { X = 2, Y = 3 };
       var vector2 = new Vector() { X = 4, Y = 5 };
       var vector3 = vector1 + vector2;
       Console.WriteLine("The new vector is: X = {0}, Y = {1}.", 
           vector3.X, vector3.Y);
       Console.ReadLine();
}

The result is: The new vector is: X = 6, Y = 8.

Conclusion

We need to use operator overloading very carefully. It's easy to abuse it which can make the application hard to understand and maintain. If the operator overloading is not necessary to use and might make the code look bad, we should avoid it.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)


Ref: MSDN

Thursday, May 12, 2016

EventHandler with Generics in C#

In previous post, we saw the basic usage of EventHandler in C# here. In this post, we will see how to use EventHandler with generics in C#.

EventHandler With Generics

The EventHandler<TEventArgs> is a predefined delegate that represents an event handler method for event with data. We can use an object of class derived from EventArgs with such an EventHandler. This is essentially useful when we have an event where we want to use some data.


Event With Generics in C#


If we look at the implementation of EventHandler with generics, this is how it's defined:


public delegate void EventHandler<TEventArgs>(object sender, 
            TEventArgs e);

Suppose, we have a User class where we want to trigger an event whenever the user's name is updated. We want the event arguments to have the old user name and the new user name. On user name update, we want to print the old and new user name.

We will first create a new UserNameUpdatedEventArgs derived from EventArgs class.


public class UserNameUpdatedEventArgs : EventArgs
{
    public string OldUserName { get; set; }
    public string NewUserName { get; set; }
}

Next, here is the User class:

public class User {     public int userId;     public string name;     public User(int id, string username)     {         userId = id;         name = username;     }
    public void UpdateUserName(string username)     {         UserNameUpdatedEventArgs args = new            UserNameUpdatedEventArgs();         args.OldUserName = name;         args.NewUserName = username;         OnUserNameUpdated(args);     //event          name = username;     }
    protected virtual void OnUserNameUpdated(           UserNameUpdatedEventArgs e)     {         EventHandler<UserNameUpdatedEventArgs> handler =                 UserNameUpdated;         if (handler != null)         {             handler(this, e);         }     }
    public event EventHandler<UserNameUpdatedEventArgs>        UserNameUpdated; }

Please note how the event args are set in the UpdateUserName method. We set the old and new user names in the UserNameUpdatedEventArgs object and pass it to the event. 

In order to use it in the main method, we simply create a handler and use it like this:

static void Main(string[] args) {       User user = new User(1, "Abhi");       user.UserNameUpdated += program_UserNameUpdated;       user.UpdateUserName("Abhi Jain");       Console.ReadLine(); }
static void program_UserNameUpdated(object sender,       UserNameUpdatedEventArgs e) {     Console.WriteLine("The user name was updated from           {0} to {1}.", e.OldUserName, e.NewUserName); }

The output looks like this:

The user name was updated from Abhi to Abhi Jain

Conclusion

So we saw how to use EventHandler with generics in this post. This is pretty useful when we need to pass in special data.
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)