Engineering Notes 133

Created by admin on Fri, 06/01/2012 - 17:18
Sub Topic: 
Operator Overloading
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&nbsp;<a href="http://msdn.microsoft.com/en-us/library/57198473%28v=vs.71%29.aspx">Operator Overloading Sample</a>&nbsp;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&nbsp;<code>Complex</span></code>&nbsp;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&nbsp;<strong>ToString</strong>&nbsp;method.</p> <pre> // complex.cs</pre> <pre> using System;</pre> <pre> &nbsp;</pre> <pre> public struct Complex </pre> <pre> {</pre> <pre> &nbsp;&nbsp; public int real;</pre> <pre> &nbsp;&nbsp; public int imaginary;</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; public Complex(int real, int imaginary) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.real = real;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.imaginary = imaginary;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Declare which operator to overload (+), the types </pre> <pre> &nbsp;&nbsp;&nbsp;// that can be added (two Complex objects), and the </pre> <pre> &nbsp;&nbsp;&nbsp;// return type (Complex):</pre> <pre> &nbsp;&nbsp; public static Complex operator +(Complex c1, Complex c2) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;&nbsp; // Override the ToString method to display an complex number in the suitable format:</pre> <pre> &nbsp;&nbsp; public override string ToString()</pre> <pre> &nbsp;&nbsp; {</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(String.Format(&quot;{0} + {1}i&quot;, real, imaginary));</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; public static void Main() </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Complex num1 = new Complex(2,3);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Complex num2 = new Complex(3,4);</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add two Complex objects (num1 and num2) through the</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // overloaded plus operator:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Complex sum = num1 + num2;</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp; // Print the numbers and the sum using the overriden ToString method:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;First complex number:&nbsp; {0}&quot;,num1);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;Second complex number: {0}&quot;,num2);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;The sum of the two numbers: {0}&quot;,sum);</pre> <pre> </pre> <pre> &nbsp;&nbsp;&nbsp;}</pre> <pre> }</pre> <h4> Output</h4> <pre> First complex number:&nbsp; 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&nbsp;<code>DBBool.dbTrue</span></code>,&nbsp;<code>DBBool.dbFalse</span></code>, and&nbsp;<code>DBBool.dbNull</span></code>, where the&nbsp;<code>dbNull</span></code>&nbsp;member indicates an unknown value.</p> <p><strong>Note</strong>&nbsp;&nbsp;&nbsp;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> &nbsp;</pre> <pre> public struct DBBool</pre> <pre> {</pre> <pre> &nbsp;&nbsp; // The three possible DBBool values:</pre> <pre> &nbsp;&nbsp; public static readonly DBBool dbNull = new DBBool(0);</pre> <pre> &nbsp;&nbsp; public static readonly DBBool dbFalse = new DBBool(-1);</pre> <pre> &nbsp;&nbsp; public static readonly DBBool dbTrue = new DBBool(1);</pre> <pre> &nbsp;&nbsp; // Private field that stores -1, 0, 1 for dbFalse, dbNull, dbTrue:</pre> <pre> &nbsp;&nbsp; int value; </pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Private constructor. The value parameter must be -1, 0, or 1:</pre> <pre> &nbsp;&nbsp; DBBool(int value) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.value = value;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Implicit conversion from bool to DBBool. Maps true to </pre> <pre> &nbsp;&nbsp;&nbsp;// DBBool.dbTrue and false to DBBool.dbFalse:</pre> <pre> &nbsp;&nbsp; public static implicit operator DBBool(bool x) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x? dbTrue: dbFalse;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Explicit conversion from DBBool to bool. Throws an </pre> <pre> &nbsp;&nbsp;&nbsp;// exception if the given DBBool is dbNull, otherwise returns</pre> <pre> &nbsp;&nbsp; // true or false:</pre> <pre> &nbsp;&nbsp; public static explicit operator bool(DBBool x) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (x.value == 0) throw new InvalidOperationException();</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x.value &gt; 0;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Equality operator. Returns dbNull if either operand is dbNull, </pre> <pre> &nbsp;&nbsp;&nbsp;// otherwise returns dbTrue or dbFalse:</pre> <pre> &nbsp;&nbsp; public static DBBool operator ==(DBBool x, DBBool y) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (x.value == 0 || y.value == 0) return dbNull;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x.value == y.value? dbTrue: dbFalse;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Inequality operator. Returns dbNull if either operand is</pre> <pre> &nbsp;&nbsp; // dbNull, otherwise returns dbTrue or dbFalse:</pre> <pre> &nbsp;&nbsp; public static DBBool operator !=(DBBool x, DBBool y) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (x.value == 0 || y.value == 0) return dbNull;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x.value != y.value? dbTrue: dbFalse;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Logical negation operator. Returns dbTrue if the operand is </pre> <pre> &nbsp;&nbsp;&nbsp;// dbFalse, dbNull if the operand is dbNull, or dbFalse if the</pre> <pre> &nbsp;&nbsp; // operand is dbTrue:</pre> <pre> &nbsp;&nbsp; public static DBBool operator !(DBBool x) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new DBBool(-x.value);</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Logical AND operator. Returns dbFalse if either operand is </pre> <pre> &nbsp;&nbsp;&nbsp;// dbFalse, dbNull if either operand is dbNull, otherwise dbTrue:</pre> <pre> &nbsp;&nbsp; public static DBBool operator &amp;(DBBool x, DBBool y) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new DBBool(x.value &lt; y.value? x.value: y.value);</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Logical OR operator. Returns dbTrue if either operand is </pre> <pre> &nbsp;&nbsp;&nbsp;// dbTrue, dbNull if either operand is dbNull, otherwise dbFalse:</pre> <pre> &nbsp;&nbsp; public static DBBool operator |(DBBool x, DBBool y) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new DBBool(x.value &gt; y.value? x.value: y.value);</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Definitely true operator. Returns true if the operand is </pre> <pre> &nbsp;&nbsp;&nbsp;// dbTrue, false otherwise:</pre> <pre> &nbsp;&nbsp; public static bool operator true(DBBool x) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x.value &gt; 0;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Definitely false operator. Returns true if the operand is </pre> <pre> &nbsp;&nbsp;&nbsp;// dbFalse, false otherwise:</pre> <pre> &nbsp;&nbsp; public static bool operator false(DBBool x) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x.value &lt; 0;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Overload the conversion from DBBool to string:</pre> <pre> &nbsp;&nbsp; public static implicit operator string(DBBool x) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return x.value &gt; 0 ? &quot;dbTrue&quot;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : x.value &lt; 0 ? &quot;dbFalse&quot;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : &quot;dbNull&quot;;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Override the Object.Equals(object o) method:</pre> <pre> &nbsp;&nbsp; public override bool Equals(object o) </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try </pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (bool) (this == (DBBool) o);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch </pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Override the Object.GetHashCode() method:</pre> <pre> &nbsp;&nbsp; public override int GetHashCode() </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return value;</pre> <pre> &nbsp;&nbsp; }</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp; // Override the ToString method to convert DBBool to a string:</pre> <pre> &nbsp;&nbsp; public override string ToString() </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (value) </pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case -1:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &quot;DBBool.False&quot;;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 0:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &quot;DBBool.Null&quot;;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 1:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &quot;DBBool.True&quot;;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new InvalidOperationException();</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre> <pre> &nbsp;&nbsp; }</pre> <pre> }</pre> <pre> &nbsp;</pre> <pre> class Test </pre> <pre> {</pre> <pre> &nbsp;&nbsp; static void Main() </pre> <pre> &nbsp;&nbsp;&nbsp;{</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DBBool a, b;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = DBBool.dbTrue;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = DBBool.dbNull;</pre> <pre> &nbsp;</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine( &quot;!{0} = {1}&quot;, a, !a);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine( &quot;!{0} = {1}&quot;, b, !b);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine( &quot;{0} &amp; {1} = {2}&quot;, a, b, a &amp; b);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine( &quot;{0} | {1} = {2}&quot;, a, b, a | b);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Invoke the true operator to determine the Boolean </pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// value of the DBBool variable:</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (b)</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;b is definitely true&quot;);</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</pre> <pre> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;b is not definitely true&quot;);&nbsp;&nbsp; </pre> <pre> &nbsp;&nbsp;&nbsp;}</pre> <pre> }</pre> <h4> Output</h4> <pre> !DBBool.True = DBBool.False</pre> <pre> !DBBool.Null = DBBool.Null</pre> <pre> DBBool.True &amp; DBBool.Null = DBBool.Null</pre> <pre> DBBool.True | DBBool.Null = DBBool.True</pre> <pre> b is not definitely true</pre> <p>&nbsp;</p>
engnotes_star_rating: 

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.