zoukankan      html  css  js  c++  java
  • 重载操作符语法

    重载操作符
    要求重载方法的参数至少有一个参数与重载方法的类型一样。
    运算符参数不能使用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.转换不会引起异常。

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

  • 相关阅读:
    Log4net使用总结,防止自定义的logger和root重复写入日志
    如何实现asp.net中FileUpload文件类型过滤功能
    C# 中 SerialPort.GetPortNames 获取串口号错误的问题及解决方法
    GOF 设计模式 [转载]
    CSS常用字体属性(多出的文本隐藏,或者以省略号的形式显示)和背景样式以及背景图的2个不常用属性:backgroundorigin和backgroundclip
    关于CSS各种选择器,还有各种引入样式表的区别,import导入样式表,在介绍一些伪类选择器
    MV*详解
    简易刮刮乐源码
    Gulp开发教程
    小程序的那些坑
  • 原文地址:https://www.cnblogs.com/Jax/p/891984.html
Copyright © 2011-2022 走看看