Casting operators

17 בMarch 2010

one comment

Casting operators

 

Many times we’ve encountered the need to cast a variable
from one type to another.  On many occasions we couldn’t
and therefore had to write our own conversion methods. Many
of these occasions the conversion methods involved our own classes.

In this post I will demonstrate the casting operators that will allow
as to have an implicit or explicit conversions between our types.

These operators has the reserved words implicit and explicit inside
their declaration without operator sign (+, –, =, == etc.), and it
looks like this:

public static implicit/explicit operator MyTargetType(MySourceType parameter)

 

It is important to mention that I cannot implement both explicit and implicit
casting at the same direction That’s because If I’ve already implemented
an implicit casting I can call it explicitly as well, and implementing the
same casting both implicitly and explicitly will cause ambiguity and
won’t compile.

I’ve chose to demonstrate casting between to type of List-derived
custom class called MyList. My Goal is to cast between MyList<MyAbstract>
and MyList<MyDerived> where MyDerived derived from MyAbstract but
that is of course not the case between MyList<MyAbstract> and
MyList<MyDerived>.

At the end of the process the code written below will be operational:

 

    MyList<MyAbstract> abstractsList = new MyList<MyAbstract>();

       //Implicit

     MyList<MyDerived> derived = abstractsList;

        //Explicit

     abstractsList = (MyList<MyAbstract>)derived;

     

     

     

MyList declaration will look like that:

public class MyList<T> : List<T> where T : MyAbstract

 

Implicit casting:

To have our implicit casting work we have to write an implicit operator
that will look like this:

    public static implicit operator MyList<T>(MyList<MyAbstract> list)

          {

     

              MyList<T> result = new MyList<T>();

              //Note : If the item is not of type T - a null value will be entered

              list.ForEach(item => AddItem(result, item));

     

              return result;

          }

    

         private static void AddItem(MyList<T> result, MyAbstract item)

         {

             T itemToAdd = item as T;

             if (itemToAdd == null && item != null)

             {

                

                 throw new InvalidCastException(string.Format("Invalid cast between {0} and {1}"

                     , item.GetType().Name, typeof(T).Name));

             }

             result.Add(itemToAdd);

         }

 

In order to simplify the operator I’ve extracted the casting logic to a  different method
called AddItem, which is responsible to add the item to our list and throw the
InvalidCastException in case of an illegal casting.

Explicit casting:

Almost the same as implicit casting operator with one difference: The reserved word
explicit is written in it’s declaration. Let’s see onefor example:

public static explicit operator MyList<MyAbstract>(MyList<T> list)

       {

 

           MyList<MyAbstract> result = new MyList<MyAbstract>();

           

           list.ForEach(item => result.Add(item as MyAbstract));

 

           return result;

       }

 

Because I used the explicit operator to cat between the generic
type parameter (T)  and it’s base type (MyAbstract) I didn’t
have to use any validation.

By opening RedGate’s reflector and browse through to the Nullable<T>
implementation you can find another great example:

Implicit casting between T and T?:

public static implicit operator T?(T value)

{

    return new T?(value);

}

Explicit casting between T? and T
public static explicit operator T(T? value)

{

    return value.Value;

}


 

Summary:

Casting operators has the same goal as every other
operator overloading : simplify our code. In this post I’ve
demonstrated the implementation of these operators for
casting between two types of List<T> derived classes.

kick it on DotNetKicks.com

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. Leo12 בAugust 2010 ב 12:21

    Hi Ran
    You should cast the blog to english ;o
    Nice
    Leo

    Reply