//from MSDN
运算符 | 可重载性 |
---|---|
+, -, !, ~, ++, --, true, false | 可以重载这些一元运算符。 |
+, -, *, /, %, &, |, ^, <<, >> | 可以重载这些二进制运算符。 |
==, !=, <, >, <=, >= | 可以重载这些比较运算符(但请参见下面的说明)。 |
&&, || | 不能重载条件逻辑运算符,但可使用 & 和 | 对其进行计算,可以重载 & 和 |;请参见 7.11.2 用户定义的条件逻辑运算符。 |
[] | 不能重载数组索引运算符,但可定义索引器。 |
() | 不能重载转换运算符,但可定义新的转换运算符(请参见 explicit 和 implicit)。 |
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= | 不能重载赋值运算符,但例外的是可使用 +(该运算符可被重载)计算 +=。 |
=, ., ?:, ->, new, is, sizeof, typeof | 不能重载这些运算符。 |
运算符重载允许为运算指定用户定义的运算符实现,其中一个或两个操作数是用户定义的类或结构类型。本教程包含两个示例。第一个示例展示如何使用运算符重载创建定义复数加法的复数类。第二个示例展示如何使用运算符重载实现三值的逻辑类型。
示例 1
本示例展示如何使用运算符重载创建定义复数加法的复数类 Complex
。本程序使用 ToString 方法的重载显示数字的虚部和实部以及加法结果。
// complex.cs using System; public struct Complex { public int real; public int imaginary; public Complex(int real, int imaginary) { this.real = real; this.imaginary = imaginary; } // Declare which operator to overload (+), the types // that can be added (two Complex objects), and the // return type (Complex): public static Complex operator +(Complex c1, Complex c2) { return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary); } // Override the ToString method to display an complex number in the suitable format: public override string ToString() { return(String.Format("{0} + {1}i", real, imaginary)); } public static void Main() { Complex num1 = new Complex(2,3); Complex num2 = new Complex(3,4); // Add two Complex objects (num1 and num2) through the // overloaded plus operator: Complex sum = num1 + num2; // Print the numbers and the sum using the overriden ToString method: Console.WriteLine("First complex number: {0}",num1); Console.WriteLine("Second complex number: {0}",num2); Console.WriteLine("The sum of the two numbers: {0}",sum); } }
输出
First complex number: 2 + 3i Second complex number: 3 + 4i The sum of the two numbers: 5 + 7i
示例 2
本示例展示如何使用运算符重载实现三值的逻辑类型。该类型的可能值有 DBBool.dbTrue
、DBBool.dbFalse
和 DBBool.dbNull
,其中 dbNull
成员表示未知值。
注意 定义 True 和 False 运算符只对表示 True、False 和 Null(既非 True 也非 False)的类型有用,如数据库中使用的类型。
// dbbool.cs using System; public struct DBBool { // The three possible DBBool values: public static readonly DBBool dbNull = new DBBool(0); public static readonly DBBool dbFalse = new DBBool(-1); public static readonly DBBool dbTrue = new DBBool(1); // Private field that stores -1, 0, 1 for dbFalse, dbNull, dbTrue: int value; // Private constructor. The value parameter must be -1, 0, or 1: DBBool(int value) { this.value = value; } // Implicit conversion from bool to DBBool. Maps true to // DBBool.dbTrue and false to DBBool.dbFalse: public static implicit operator DBBool(bool x) { return x? dbTrue: dbFalse; } // Explicit conversion from DBBool to bool. Throws an // exception if the given DBBool is dbNull, otherwise returns // true or false: public static explicit operator bool(DBBool x) { if (x.value == 0) throw new InvalidOperationException(); return x.value > 0; } // Equality operator. Returns dbNull if either operand is dbNull, // otherwise returns dbTrue or dbFalse: public static DBBool operator ==(DBBool x, DBBool y) { if (x.value == 0 || y.value == 0) return dbNull; return x.value == y.value? dbTrue: dbFalse; } // Inequality operator. Returns dbNull if either operand is // dbNull, otherwise returns dbTrue or dbFalse: public static DBBool operator !=(DBBool x, DBBool y) { if (x.value == 0 || y.value == 0) return dbNull; return x.value != y.value? dbTrue: dbFalse; } // Logical negation operator. Returns dbTrue if the operand is // dbFalse, dbNull if the operand is dbNull, or dbFalse if the // operand is dbTrue: public static DBBool operator !(DBBool x) { return new DBBool(-x.value); } // Logical AND operator. Returns dbFalse if either operand is // dbFalse, dbNull if either operand is dbNull, otherwise dbTrue: public static DBBool operator &(DBBool x, DBBool y) { return new DBBool(x.value < y.value? x.value: y.value); } // Logical OR operator. Returns dbTrue if either operand is // dbTrue, dbNull if either operand is dbNull, otherwise dbFalse: public static DBBool operator |(DBBool x, DBBool y) { return new DBBool(x.value > y.value? x.value: y.value); } // Definitely true operator. Returns true if the operand is // dbTrue, false otherwise: public static bool operator true(DBBool x) { return x.value > 0; } // Definitely false operator. Returns true if the operand is // dbFalse, false otherwise: public static bool operator false(DBBool x) { return x.value < 0; } // Overload the conversion from DBBool to string: public static implicit operator string(DBBool x) { return x.value > 0 ? "dbTrue" : x.value < 0 ? "dbFalse" : "dbNull"; } // Override the Object.Equals(object o) method: public override bool Equals(object o) { try { return (bool) (this == (DBBool) o); } catch { return false; } } // Override the Object.GetHashCode() method: public override int GetHashCode() { return value; } // Override the ToString method to convert DBBool to a string: public override string ToString() { switch (value) { case -1: return "DBBool.False"; case 0: return "DBBool.Null"; case 1: return "DBBool.True"; default: throw new InvalidOperationException(); } } } class Test { static void Main() { DBBool a, b; a = DBBool.dbTrue; b = DBBool.dbNull; Console.WriteLine( "!{0} = {1}", a, !a); Console.WriteLine( "!{0} = {1}", b, !b); Console.WriteLine( "{0} & {1} = {2}", a, b, a & b); Console.WriteLine( "{0} | {1} = {2}", a, b, a | b); // Invoke the true operator to determine the Boolean // value of the DBBool variable: if (b) Console.WriteLine("b is definitely true"); else Console.WriteLine("b is not definitely true"); } }
输出
!DBBool.True = DBBool.False !DBBool.Null = DBBool.Null DBBool.True & DBBool.Null = DBBool.Null DBBool.True | DBBool.Null = DBBool.True b is not definitely true
当
&&
或||
的操作数所属的类型声明了适用的用户定义的operator
&
或operator
|
时,下列两个条件必须都为真(其中T
是声明的选定运算符的类型):
- 选定运算符的返回类型和每个参数的类型都必须为
T
。换言之,该运算符必须计算类型为T
的两个操作数的逻辑AND
或逻辑OR
,且必须返回类型为T
的结果。T
必须包含关于operator
true
和operator
false
的声明。如果这两个要求中有一个未满足,则发生编译时错误。如果这两个要求都满足,则通过将用户定义的
operator
true
或operator
false
与选定的用户定义的运算符组合在一起来计算&&
或||
运算:
x
&&
y
运算按T.false(x) ?
x :
T.&(x,
y)
进行计算,其中T.false(x)
是T
中声明的operator
false
的调用,T.&(x,
y)
是选定operator
&
的调用。换言之,首先计算x
,并对结果调用operator
false
以确定x
是否肯定为假。然后,如果x
肯定为假,则运算结果为先前为x
计算的值。否则将计算y
,并对先前为x
计算的值和为y
计算的值调用选定的operator &
以产生运算结果。x
||
y
运算按T.true(x) ?
x :
T.|(x,
y)
进行计算,其中T.true(x)
是T
中声明的operator
true
的调用,T.|(x,
y)
是选定operator
|
的调用。换言之,首先计算x
,并对结果调用operator
true
以确定x
是否肯定为真。然后,如果x
肯定为真,则运算结果为先前为x
计算的值。否则将计算y
,并对先前为x
计算的值和为y
计算的值调用选定的operator
|
以产生运算结果。在这两个运算中,
x
给定的表达式只计算一次,y
给定的表达式要么不计算,要么只计算一次。
[ ]:索引器声明(不是运算符重载)
public int this [int index] // Indexer declaration { get { // Check the index limits. if (index < 0 || index >= 100) return 0; else return myArray[index]; } set { if (!(index < 0 || index >= 100)) myArray[index] = value; } }