重载操作符语法

重载操作符
要求重载方法的参数至少有一个参数与重载方法的类型一样。
运算符参数不能使用ref/out修饰符。

需许要注意的要点如下:
  1. &&和||不能被直接重载,但使用&和|进入计算则可以被重载
  2. [ ]不能被重载,可以使用索引器来代替它完成所需操作
  3. ( )不能被重载,代替此运算符的方式是定义新的转换运算符 ,即隐式/显示转换运算符
  4. 逻辑运算符必须成对重载==和!=
  5. 赋值运算符=不能被重载, +=也属于赋值运算符

        //operator是运算符重载的关键字
        
//重载二元运算符
        public static ThreeD operator +(ThreeD op1, ThreeD op2)
        
{
            ThreeD result 
= new ThreeD();
            result.x 
= op1.x + op2.x;
            result.y 
= op1.y + op2.y;
            result.z 
= op1.z + op2.z;

            
return result;
        }


        
//可以多次重载同一运算符
        public static ThreeD operator -(ThreeD op1, ThreeD op2)
        
{
            ThreeD result 
= new ThreeD();
            result.x 
= op1.x - op2.x;
            result.y 
= op1.y - op2.y;
            result.z 
= op1.z - op2.z;

            
return result;
        }


        
//重载一元运算符
        public static ThreeD operator -(ThreeD op)
        
{
            ThreeD result 
= new ThreeD();
            result.x 
= -op.x;
            result.y 
= -op.y;
            result.z 
= -op.z;

            
return result;
        }

对象+整型 与 整型 + 对象 是不一样的,所以要重载两次:
        public static ThreeD operator +(ThreeD op1, int op2)
        
{
            ThreeD result 
= new ThreeD();
            result.x 
= op1.x + op2;
            result.y 
= op1.y + op2;
            result.z 
= op1.z + op2;

            
return result;
        }


        
public static ThreeD operator +(int op1, ThreeD op2)
        
{
            ThreeD result 
= new ThreeD();
            result.x 
= op1 + op2.x;
            result.y 
= op1 + op2.y;
            result.z 
= op1 + op2.z;

            
return result;
        }

重载关系运算符要“成对重载”,比如说<和>,不能只重载其中重载一个。先重载<,然后可以利用<重载>:
        public static bool operator <(ThreeD op1, ThreeD op2)
        
{
            
if ((op1.x < op2.x) && (op1.y < op2.y) && (op1.z < op2.z))
            
{
                
return true;
            }

            
else
            
{
                
return false;
            }

        }


        
public static bool operator >(ThreeD op1, ThreeD op2)
        
{
            
if (op1 < op2)
            
{
                
return false;
            }

            
else
            
{
                
return true;
            }

        }

关系运算符==,重载时候需要同时覆写Equal(object)方法和GetHashCode()方法,如下:
        public static bool operator ==(ThreeD a, ThreeD b)
        
{
            
// If both are null, or both are same instance, return true.
            if (System.Object.ReferenceEquals(a, b))
            
{
                
return true;
            }


            
// If one is null, but not both, return false.
            if (((object)a == null|| ((object)b == null))
            
{
                
return false;
            }


            
// Return true if the fields match:
            return a.x == b.x && a.y == b.y && a.z == b.z;
        }


        
public static bool operator !=(ThreeD op1, ThreeD op2)
        
{
            
return !(op1 == op2);
        }


        
public override bool Equals(Object obj)
        
{
            
if (obj == null)
            
{
                
return false;
            }


            ThreeD p 
= obj as ThreeD;
            
if ((object)p == null)
            
{
                
return false;
            }


            
return ((this.x == p.x) && (this.y == p.y) && (this.z == p.z));
        }


        
public override int GetHashCode()
        
{
            
return x ^ y ^ z;
        }

重载true和false,也要成对出现,同上。可以认为true/false也是运算符。

重载逻辑运算符,一共5个:&    |    !    &&    ||
!只是对true的取反,很容易实现。
&&与||是不能被重载的,编译器会报错。只有通过实现&与|的重载,还要实现true与false的重载,同时满足:
    重载的&与|的返回类型与参数类型必须是    重载运算符的类型。
实现如下:ThreeD定义见前面
        public static ThreeD operator &(ThreeD op1, ThreeD op2)
        
{
            
if ((op1.x != 0&& (op1.y != 0&& (op1.z != 0&
                (op2.x 
!= 0&& (op2.y != 0&& (op2.z != 0)
                )
            
{
                
return new ThreeD(111);
            }

            
else
            
{
                
return new ThreeD(000);
            }

        }
这样,&&与||对象自动可用,操作如下:如果重载的true(对应||)或false(对应&&)检验第一个操作数,如果它能确定运算的结果,那么直接返回,否则,使用相应的重载&或|来判断结果——短路运算符的原理。

转换运算符:
有两种:隐式(implicit)和显示(explicit)
implicit转换,自动调用转换方法。
explicit转换,要强制转换类型。
        public static implicit operator int(ThreeD op)
        
{
            
return op.x * op.y * op.z;
        }


        
public static explicit operator String(ThreeD op)
        
{
            
return op.x.ToString() + op.y.ToString() + op.z.ToString();
        }


        
static void Main(string[] args)
        
{
            
int i = c;
            String s 
= (String)c;
        }

转换操作符的约束:
    不能定义从double到int的类型转换,可以实现自定义类型与系统类型的转换。
    不能定义Object和其他自定义类型的转换。
    不能给相同的源和目标同时定义implicit和explicit转换。
    不能定义基类到派生类的转换。
    不能定义接口到其他类型的转换。
implicit和explicit的选择:
    隐式转换至用于与在转换不会引起错误的环境,满足以下两条才创建隐式转换:
        1.不丢失信息,如截断/溢出/丢失正负号
        2.转换不会引起异常。

复合运算符不能被重载,因为它们总是被分解开来,如+= ,但是,如果已经重载了+,那么+=就自动可以使用

posted @ 2007-09-13 17:14  包建强  Views(1369)  Comments(2Edit  收藏  举报