Overloading 'Cast' Operator in C# 4.0

Kishork80
Posted by in C# category on for Beginner level | Views : 21444 red flag
Rating: 4.67 out of 5  
 3 vote(s)

We all are aware of Operator overloading concept in C#. We can also overload ‘Cast’ operator but a little bit of workaround is required here.

Introduction

We all are aware of Operator overloading concept in C#. We can also overload ‘Cast’ operator but a little bit of workaround is required here. We cannot overload the cast operator directly. We need to understand ‘User-defined casts ‘ which allow us to define custom cast behavior and overload ‘cast’ operator like operator overloading.


Types of cast

There are two types of Cast.

  1.  Implicit
  2. Explicit

//Example code

int x = 100;
long y = 0;
//implicit cast
y = x;
//explicit cast
short s = (short)x;

 

For Predefined data types the implicit and exlicit cast works easily as we saw them.

 

Code Part:

Now Coming to the point!!!

 In C# we are allowed to define our own data types  such as structures and classes, But the question is how to support implicit and explicit cast for them. How do we convert a struct or class to predefined data type.

 

Like e.g.

 

<struct/class> instance = new <struct/class>();
float f = instance; // We want to cast instance to float.
Console.WriteLine(f);
//The above code will give compile error.

 

How to achieve this?

To support this we will need the facility to support casts to and from those data types. The inside workout is that we can define a cast as a member operator of one of the relevant classes. Our cast operator must be marked as either implicit or explicit to indicate how we are intending it to be used.

if we know that the cast is always safe no matter what the value held by the source variable, then we define it as ‘implicit cast’.

If, however, we come to know that there is a risk of something going wrong for certain values — perhaps some loss of data or an exception being thrown — then we must  make the cast as ‘explicit cast’.

Having said So, move on and fasten your seat belts !\

Basic Syntax  for ’cast’ overloading:

 

//implicit cast

public static implicit operator <Predefined Data type> (<Struct/Class> instance)

   {

//implicit cast logic

return <Predefined Data type>;

   }

//explicit cast

public static explicit operator <Struct/Class> (<Predefined Data type> value)

  {

//explicit cast logic

return <Struct/Class instance>;

  }

 

What do we notice here?

The syntax is same to Opertor overloading. That is why it is said ‘Cast’ overloading.

The return type of the operator defines the target type of the cast operation,   and the single parameter is the source object for the conversion.

Now the code logic :

We define a struct (for simplicity nothing else,Cast operator works equally for both class as well as struct)

  ‘ Currency’ , which holds a positive USD ($) monetary value.

  C# provides the decimal type for this purpose,  but it is possible that we will still want to write our own struct or class to represent monetary values if we want to perform sophisticated financial processing and therefore want to implement specific methods on such a class or struct.

 Steps to be followed:

 

v  Create a C# console application and create the structure with member fields and methods as per the below code.

 

struct Currency
{

            //memeber fields
            uint _Dollars;
            ushort _Cents; 

            //Parameter Constructor to assign the fields
            public Currency(uint dollars, ushort cents)
            {
                this._Dollars = dollars;
                this._Cents = cents;
            }

            //--------------Now User defined cast part code--------------------

            /*
                1> Implicit cast.Notice 'implicit' keyword here
                By assuming that we want to convert Currency instances to float values.

      */

            public static implicit operator float(Currency value)
            {
                return value._Dollars + (value._Cents / 100.0f);
            }

            /*  2> Explicit cast.Notice 'explicit' keyword here
                By assuming that we want to convert float instances to Currency values.

       */

 

            public static explicit operator Currency(float value)
            {
/*To avoid any overflow exception and to be on safer side  we use 'checked provided by C# */

                checked
                {
                    uint dollars = (uint)value;
                    ushort cents = Convert.ToUInt16((value - dollars) * 100);
                    return new Currency(dollars, cents);
                }

           }

           

            /*override ToString() method*/

            public override string ToString()
            {
                return string.Format("${0}.{1, - 2:00} ", _Dollars, _Cents);
            }

}

 

 

v  Just to Test the above code execute the below code in Main() part of the program.

 

public static void Main(string[] args)
{

           //Just call the implict cast for test
           Currency balance = new Currency(10, 50);
           /*Without code for the 'implicit' casting we get the Error:Cannot implicitly convert type 'Currency' to 'float'    */

           float f = balance; // We want f to be set to 10.5
           Console.WriteLine(f);//OUTPUT : 10.5

           //Just call the 'explicit' cast for test
           /*Without code for the 'implicit' casting we get the Error:Cannot convert type 'float' to 'Currency'   */

           float amount = 45.63f;
           Currency amountCur = (Currency)amount;
           Console.WriteLine(amountCur);//OUTPUT :45.63
}

 

Conclusion

We saw cast overloading which is easy to understand and code as well.
Cheers-Kishor Kumar

Page copy protected against web site content infringement by Copyscape

About the Author

Kishork80
Full Name: kishor kumar
Member Level: Starter
Member Status: Member
Member Since: 7/1/2010 2:49:48 AM
Country: India
kishor kumar
http://www.dotnetfunda.com
Having 6 pyears of exp in dot net and still counting...

Login to vote for this post.

Comments or Responses

Posted by: Abhi2434 on: 7/10/2010
checked throws OverflowException. Use unchecked to be in safer side.

Wheever you cast any object to anything, use of checked will ensure that the expression will throw exception if it Overflows.

UnChecked avoids this.
Posted by: Ajnreddy on: 7/13/2010
Very good article kishore. Keep up the good work.
Posted by: Raja on: 7/16/2010
I do not think that the article code snippet has been updated till now based on @Abhi2324 comment, still the code say checked.

Or I am missing something here?
Posted by: Kishork80 on: 7/16/2010
'checked' was required to avoid any overflow exception and to be on safer side.
we can also modify the code as per below block:

unchecked
{
uint dollars = (uint)value;
ushort cents = Convert.ToUInt16((value - dollars) * 100);
return new Currency(dollars, cents);
}

Login to post response

Comment using Facebook(Author doesn't get notification)