Friday, January 04, 2008

Designing new primitive types !!!

We all write library[ I guess all of us at some point of time ], consider a situation where we have to develop a Graphics Library or a Math Library, and possibly we have to define a type say ‘Point’ or ‘Rational Number’. For a Graphics Library, I reckon a ‘Point’ is an essential type, which contains X and Y coordinate.

To develop a complex type( here Point type )we can create a class or a structure, and as we all know a class would be considered as Reference type, but a Structure will be considered as a Value type, or as a primitive type such as ‘int’, now how to decide whether I should go for a class or reference type …. If I think from the operation perspective, for example I want my type should be used like a primitive type, hence I would be able to write this code block ..
Point p1 = new Point(200, 100);
Point p2 = 50;
Point p3 = p1 + p2;
p3 += 10;
Console.WriteLine( "Default Format = {0}", p1 );
Console.WriteLine( ": Format = {0::}", p2 );
Console.WriteLine("Default Format = {0}", p3);


Well, we can write the above code block irrespective of ‘Point’ is a class or a structure, but writing ‘Point’ as a class could be a problem since …
a) Could be NULL[ at times this cause a problem ]
b) ‘=’ sign refer to a reference not value.
c) Heap based, accessing Stack is faster than Heap.
d) Array allocates references not Value… this could be a problem also.


Defining a Structure[ or we can say we will be able to define Point as a primitive type ] we can get rid of all the above problems, does it sound interesting ? if so please check out Point structure code base .....

public struct Point: IFormattable
{
const int _defaultY = 100;
private int _x;
private int _y;

public Point(int x, int y)
{
_x = x;
_y = y;
}

public int X
{
get { return _x; }
}

public int Y
{
get { return _y; }
}

public static implicit operator Point(int x)
{
return new Point(x, _defaultY);
}

public static explicit operator Int16(Point p)
{
return(Int16) p.X;
}

public static Point operator+(Point p1, Point p2)
{
return new Point((p1.X + p2.X), (p1.Y + p2.Y));
}

public static bool operator ==(Point p1, Point p2)
{
bool flag = false;
if (p1.X == p2.X && p1.Y == p2.Y)
{
flag = true;
}
return flag;
}

public static bool operator !=(Point p1, Point p2)
{
bool flag = false;
if (p1.X != p2.X && p1.Y != p2.Y)
{
flag = true;
}
return flag;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override string ToString()
{
return "X = " + this.X + ", Y = " + this.Y;
}

#region IFormattable Members
public string ToString(string format, IFormatProvider formatProvider)
{
string str = this.ToString();
if (String.Compare(format, ":") == 0 )
{
str = "X:" + this.X + ",Y:" + this.Y;
}
return str;
}
#endregion
}