Engineering Notes 133
Created by admin on Fri, 06/01/2012 - 17:18
Sub Topic:
Operator Overloading
Department:
Chapter Name:
C SHARP AND .NET FRAMEWORK
Description:
Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type. The tutorial contains two examples.
Content:
<h1>
Operator Overloading Tutorial</h1>
<p><strong>Visual Studio .NET 2003</strong></p>
<p>This tutorial demonstrates how user-defined classes can overload operators.</p>
<h2>
Sample Files</h2>
<p>See <a href="http://msdn.microsoft.com/en-us/library/57198473%28v=vs.71%29.aspx">Operator Overloading Sample</a> to download and build the sample files discussed in this tutorial.</p>
<h2>
Further Reading</h2>
<ul>
<li>
<a href="http://msdn.microsoft.com/en-us/library/aa691324%28v=vs.71%29.aspx">7.2.2 Operator overloading</a></li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/6a71f45d%28v=vs.71%29.aspx">C# Operators</a></li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/8edha89s%28v=vs.71%29.aspx">Overloadable Operators</a></li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/eahhcxk2%28v=vs.71%29.aspx">true</a></li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/67bxt5ee%28v=vs.71%29.aspx">false</a></li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/c8f5xwh7%28v=vs.71%29.aspx">bool</a></li>
</ul>
<h2>
Tutorial</h2>
<p>Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type. The tutorial contains two examples. The first example shows how to use operator overloading to create a complex number class that defines complex addition. The second example shows how to use operator overloading to implement a three-valued logical type.</p>
<h4>
Example 1</h4>
<p>This example shows how you can use operator overloading to create a complex number class <code>Complex</span></code> that defines complex addition. The program displays the imaginary and the real parts of the numbers and the addition result using an override of the <strong>ToString</strong> method.</p>
<pre>
// complex.cs</pre>
<pre>
using System;</pre>
<pre>
</pre>
<pre>
public struct Complex </pre>
<pre>
{</pre>
<pre>
public int real;</pre>
<pre>
public int imaginary;</pre>
<pre>
</pre>
<pre>
public Complex(int real, int imaginary) </pre>
<pre>
{</pre>
<pre>
this.real = real;</pre>
<pre>
this.imaginary = imaginary;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Declare which operator to overload (+), the types </pre>
<pre>
// that can be added (two Complex objects), and the </pre>
<pre>
// return type (Complex):</pre>
<pre>
public static Complex operator +(Complex c1, Complex c2) </pre>
<pre>
{</pre>
<pre>
return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);</pre>
<pre>
}</pre>
<pre>
// Override the ToString method to display an complex number in the suitable format:</pre>
<pre>
public override string ToString()</pre>
<pre>
{</pre>
<pre>
return(String.Format("{0} + {1}i", real, imaginary));</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
public static void Main() </pre>
<pre>
{</pre>
<pre>
Complex num1 = new Complex(2,3);</pre>
<pre>
Complex num2 = new Complex(3,4);</pre>
<pre>
</pre>
<pre>
// Add two Complex objects (num1 and num2) through the</pre>
<pre>
// overloaded plus operator:</pre>
<pre>
Complex sum = num1 + num2;</pre>
<pre>
</pre>
<pre>
// Print the numbers and the sum using the overriden ToString method:</pre>
<pre>
Console.WriteLine("First complex number: {0}",num1);</pre>
<pre>
Console.WriteLine("Second complex number: {0}",num2);</pre>
<pre>
Console.WriteLine("The sum of the two numbers: {0}",sum);</pre>
<pre>
</pre>
<pre>
}</pre>
<pre>
}</pre>
<h4>
Output</h4>
<pre>
First complex number: 2 + 3i</pre>
<pre>
Second complex number: 3 + 4i</pre>
<pre>
The sum of the two numbers: 5 + 7i</pre>
<h4>
Example 2</h4>
<p>This example shows how operator overloading can be used to implement a three-valued logical type. The possible values of this type are <code>DBBool.dbTrue</span></code>, <code>DBBool.dbFalse</span></code>, and <code>DBBool.dbNull</span></code>, where the <code>dbNull</span></code> member indicates an unknown value.</p>
<p><strong>Note</strong> Defining the True and False operators is only useful for types that represent True, False, and Null (neither True nor False), as used in databases.</p>
<pre>
// dbbool.cs</pre>
<pre>
using System;</pre>
<pre>
</pre>
<pre>
public struct DBBool</pre>
<pre>
{</pre>
<pre>
// The three possible DBBool values:</pre>
<pre>
public static readonly DBBool dbNull = new DBBool(0);</pre>
<pre>
public static readonly DBBool dbFalse = new DBBool(-1);</pre>
<pre>
public static readonly DBBool dbTrue = new DBBool(1);</pre>
<pre>
// Private field that stores -1, 0, 1 for dbFalse, dbNull, dbTrue:</pre>
<pre>
int value; </pre>
<pre>
</pre>
<pre>
// Private constructor. The value parameter must be -1, 0, or 1:</pre>
<pre>
DBBool(int value) </pre>
<pre>
{</pre>
<pre>
this.value = value;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Implicit conversion from bool to DBBool. Maps true to </pre>
<pre>
// DBBool.dbTrue and false to DBBool.dbFalse:</pre>
<pre>
public static implicit operator DBBool(bool x) </pre>
<pre>
{</pre>
<pre>
return x? dbTrue: dbFalse;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Explicit conversion from DBBool to bool. Throws an </pre>
<pre>
// exception if the given DBBool is dbNull, otherwise returns</pre>
<pre>
// true or false:</pre>
<pre>
public static explicit operator bool(DBBool x) </pre>
<pre>
{</pre>
<pre>
if (x.value == 0) throw new InvalidOperationException();</pre>
<pre>
return x.value > 0;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Equality operator. Returns dbNull if either operand is dbNull, </pre>
<pre>
// otherwise returns dbTrue or dbFalse:</pre>
<pre>
public static DBBool operator ==(DBBool x, DBBool y) </pre>
<pre>
{</pre>
<pre>
if (x.value == 0 || y.value == 0) return dbNull;</pre>
<pre>
return x.value == y.value? dbTrue: dbFalse;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Inequality operator. Returns dbNull if either operand is</pre>
<pre>
// dbNull, otherwise returns dbTrue or dbFalse:</pre>
<pre>
public static DBBool operator !=(DBBool x, DBBool y) </pre>
<pre>
{</pre>
<pre>
if (x.value == 0 || y.value == 0) return dbNull;</pre>
<pre>
return x.value != y.value? dbTrue: dbFalse;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Logical negation operator. Returns dbTrue if the operand is </pre>
<pre>
// dbFalse, dbNull if the operand is dbNull, or dbFalse if the</pre>
<pre>
// operand is dbTrue:</pre>
<pre>
public static DBBool operator !(DBBool x) </pre>
<pre>
{</pre>
<pre>
return new DBBool(-x.value);</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Logical AND operator. Returns dbFalse if either operand is </pre>
<pre>
// dbFalse, dbNull if either operand is dbNull, otherwise dbTrue:</pre>
<pre>
public static DBBool operator &(DBBool x, DBBool y) </pre>
<pre>
{</pre>
<pre>
return new DBBool(x.value < y.value? x.value: y.value);</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Logical OR operator. Returns dbTrue if either operand is </pre>
<pre>
// dbTrue, dbNull if either operand is dbNull, otherwise dbFalse:</pre>
<pre>
public static DBBool operator |(DBBool x, DBBool y) </pre>
<pre>
{</pre>
<pre>
return new DBBool(x.value > y.value? x.value: y.value);</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Definitely true operator. Returns true if the operand is </pre>
<pre>
// dbTrue, false otherwise:</pre>
<pre>
public static bool operator true(DBBool x) </pre>
<pre>
{</pre>
<pre>
return x.value > 0;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Definitely false operator. Returns true if the operand is </pre>
<pre>
// dbFalse, false otherwise:</pre>
<pre>
public static bool operator false(DBBool x) </pre>
<pre>
{</pre>
<pre>
return x.value < 0;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Overload the conversion from DBBool to string:</pre>
<pre>
public static implicit operator string(DBBool x) </pre>
<pre>
{</pre>
<pre>
return x.value > 0 ? "dbTrue"</pre>
<pre>
: x.value < 0 ? "dbFalse"</pre>
<pre>
: "dbNull";</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Override the Object.Equals(object o) method:</pre>
<pre>
public override bool Equals(object o) </pre>
<pre>
{</pre>
<pre>
try </pre>
<pre>
{</pre>
<pre>
return (bool) (this == (DBBool) o);</pre>
<pre>
}</pre>
<pre>
catch </pre>
<pre>
{</pre>
<pre>
return false;</pre>
<pre>
}</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Override the Object.GetHashCode() method:</pre>
<pre>
public override int GetHashCode() </pre>
<pre>
{</pre>
<pre>
return value;</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
// Override the ToString method to convert DBBool to a string:</pre>
<pre>
public override string ToString() </pre>
<pre>
{</pre>
<pre>
switch (value) </pre>
<pre>
{</pre>
<pre>
case -1:</pre>
<pre>
return "DBBool.False";</pre>
<pre>
case 0:</pre>
<pre>
return "DBBool.Null";</pre>
<pre>
case 1:</pre>
<pre>
return "DBBool.True";</pre>
<pre>
default:</pre>
<pre>
throw new InvalidOperationException();</pre>
<pre>
}</pre>
<pre>
}</pre>
<pre>
}</pre>
<pre>
</pre>
<pre>
class Test </pre>
<pre>
{</pre>
<pre>
static void Main() </pre>
<pre>
{</pre>
<pre>
DBBool a, b;</pre>
<pre>
a = DBBool.dbTrue;</pre>
<pre>
b = DBBool.dbNull;</pre>
<pre>
</pre>
<pre>
Console.WriteLine( "!{0} = {1}", a, !a);</pre>
<pre>
Console.WriteLine( "!{0} = {1}", b, !b);</pre>
<pre>
Console.WriteLine( "{0} & {1} = {2}", a, b, a & b);</pre>
<pre>
Console.WriteLine( "{0} | {1} = {2}", a, b, a | b);</pre>
<pre>
// Invoke the true operator to determine the Boolean </pre>
<pre>
// value of the DBBool variable:</pre>
<pre>
if (b)</pre>
<pre>
Console.WriteLine("b is definitely true");</pre>
<pre>
else</pre>
<pre>
Console.WriteLine("b is not definitely true"); </pre>
<pre>
}</pre>
<pre>
}</pre>
<h4>
Output</h4>
<pre>
!DBBool.True = DBBool.False</pre>
<pre>
!DBBool.Null = DBBool.Null</pre>
<pre>
DBBool.True & DBBool.Null = DBBool.Null</pre>
<pre>
DBBool.True | DBBool.Null = DBBool.True</pre>
<pre>
b is not definitely true</pre>
<p> </p>
Add new comment