.comment-link {margin-left:.6em;}
My Photo
Name:
Location: Unspecified, Mauritius

I too, am a bug within Māyā.

My Other Blog(s) and Site(s)
Friend sites and blogs
My Recent Posts
Tutorials
Best Articles
My C-Sharp Ideas
Archives
Blog Directories

Saturday, July 23, 2005

 

Explicit Typecasts

Or also known as tranny-casts
[intermediate]

Implicit Typecasts are casts which occur when the compiler cannot directly treat one data type as another, and require "user intervention". By user intervention, I mean, user code :)

Trying to typecast a StreamReader into an ArrayList would be a bad idea. That's a typecasting that's not "meant to be" (would raise an InvalidCast Exception), and that's why the user should kick in his/her own code for it to happen.

As usual, I made another one of my useless classes, for the purpose of this tutorial. The Data class simply holds a name (string) and a DataValue (int). Also, I kicked in a few lines of code which would allow the data class to be typecasted as string (thus returning the name), or typecast as int (returning the DataValue). Check it out below:




/// <summary>
/// Simple class which holds a name (string) and a
/// value (int).
/// </summary>
public class Data
{
private string name;
private int dataValue;

/// <summary>
/// Instantiates a new Data class
/// </summary>
/// <param name="name">The name the data class
/// will hold</param>
/// <param name="dataValue">The value the data
/// class will hold</param>
public Data(string name, int dataValue)
{
this.name = name;
this.dataValue = dataValue;
}

/// <summary>
/// Gets or Sets the name
/// </summary>
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}

/// <summary>
/// Gets or sets the Data Value
/// </summary>
public int DataValue
{
get
{
return this.dataValue;
}
set
{
this.dataValue = value;
}
}

/// <summary>
/// Allow typecasting into string
/// </summary>
/// <param name="someData">The data class
/// which needs to be typecasted</param>
/// <returns>The name of the data class</returns>
public static explicit operator string(Data someData)
{
string retValue = someData.name;
return retValue;
}

/// <summary>
/// Allow typecasting into int
/// </summary>
/// <param name="someData">The data class
/// which needs to be typecasted</param>
/// <returns>The value of the data class</returns>
public static explicit operator int(Data someData)
{
int retValue = someData.dataValue;
return retValue;
}
}



The only part of this code that interests us is:



/// <summary>
/// Allow typecasting into string
/// </summary>
/// <param name="someData">The data class
/// which needs to be typecasted</param>
/// <returns>The name of the data class</returns>
public static explicit operator string(Data someData)
{
string retValue = someData.name;
return retValue;
}

/// <summary>
/// Allow typecasting into int
/// </summary>
/// <param name="someData">The data class
/// which needs to be typecasted</param>
/// <returns>The value of the data class</returns>
public static explicit operator int(Data someData)
{
int retValue = someData.dataValue;
return retValue;
}



Note that those two methods are static, and marked with the explicit and operator keywords. The first method simply contains code that is going to be executed if the user decides to typecast into a string. Note that the return type (i.e. the operation of the casting) is a string. The value in parameters is a Data class, i.e. the data class that's being typecasted into a string. The next lines of code are pretty easy. The name of the Data class is extracted by looking into the Data class passed into parameters, and this value returned (it's a string anyway).

And that's all there is to explicit typecasting. The second method does pretty much the same, but allows typecasting into an int (notice: the return type's an int). Here's how I explicitly typecasted my Data class into a string, and then an int.


/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Data myData = new Data("Bebs", 19);

Console.WriteLine((string)myData);
Console.WriteLine(((int)myData).ToString());

Console.ReadLine();

}

Yup... and it works :) The complete source code can be found below:



using System;


namespace UselessStuff
{
/// <summary>
/// MultiParam App
/// </summary>
class UselessMain
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Data myData = new Data("Bebs", 19);

Console.WriteLine((string)myData);
Console.WriteLine(((int)myData).ToString());

Console.ReadLine();

}
}

/// <summary>
/// Simple class which holds a name (string) and a
/// value (int).
/// </summary>
public class Data
{
private string name;
private int dataValue;

/// <summary>
/// Instantiates a new Data class
/// </summary>
/// <param name="name">The name the data class
/// will hold</param>
/// <param name="dataValue">The value the data
/// class will hold</param>
public Data(string name, int dataValue)
{
this.name = name;
this.dataValue = dataValue;
}

/// <summary>
/// Gets or Sets the name
/// </summary>
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}

/// <summary>
/// Gets or sets the Data Value
/// </summary>
public int DataValue
{
get
{
return this.dataValue;
}
set
{
this.dataValue = value;
}
}

/// <summary>
/// Allow typecasting into string
/// </summary>
/// <param name="someData">The data class
/// which needs to be typecasted</param>
/// <returns>The name of the data class</returns>
public static explicit operator string(Data someData)
{
string retValue = someData.name;
return retValue;
}

/// <summary>
/// Allow typecasting into int
/// </summary>
/// <param name="someData">The data class
/// which needs to be typecasted</param>
/// <returns>The value of the data class</returns>
public static explicit operator int(Data someData)
{
int retValue = someData.dataValue;
return retValue;
}
}
}


Comments:
Great explanation, just what I needed!
 
Post a Comment

Links to this post:

Create a Link



<< Home