C#中运算符重载的几点注意

这是一篇简记,因此不做特别的排版


1、运算符重载不能多态

这是最容易出问题的地方,看下面的代码

重载者如下:

public class Father {

    public int value;

    public static implicit operator int (Father father) {
        return father.value;
    }

    public static implicit operator Father(int value) {
        Father father = new Father();
        father.value = value;
        return father;
    }
}


调用者如下:

        Father father = new Father();
        father.value = 10;

        try {
            object msg = father;
            int value = (int)msg;
            Debug.LogError("1 : " + value);
        } catch (Exception e) {
            Debug.LogException(e);
        }

        try {
            int value2 = (int)father;
            Debug.LogError("2 : " + value2);
        } catch (Exception e) {
            Debug.LogException(e);
        }

        try {
            object msg = father;
            int value3 = Convert.ToInt32(msg);
            Debug.LogError("3 : " + value3);
        } catch (Exception e) {
            Debug.LogException(e);
        }

        try {
            int value4 = Convert.ToInt32(father);
            Debug.LogError("4 : " + value4);
        } catch (Exception e) {
            Debug.LogException(e);
        }

这里的第一个测试用例会抛异常,而第二个不会,这是由于第一个调用的是 object 的转换方法,第二个调用的才是复写者的方法。

这里的测试用例3会异常,测试用例4会通过。



2、Convert.ToInt32 需要使用 implicit

上文中代码的测试用例4是可以过的,但是如果将 implicit 改成 explicit 就会抛异常,考虑 Convert 的实现是可以理解的。



3、运算符重载不能泛型

如题,因此使用模板的时候最好写一个模板方法,然后由子类来调用模板方法。



4、==重载要注意防止递归

比较容易犯的错误,是在判空的时候,又调用了 equal 方法,而equal 方法又调用了 == 。比较简单的方法如下,调用 object 的equal 方法:

    public static bool operator == (EnumInt<T> a, EnumInt<T> b) {
        if (object.Equals(a, null) && object.Equals(b, null))
            return true;

        else if (object.Equals(a, null) || object.Equals(b, null))
            return false;

        else
            return a.value == b.value;
    }

    public static bool operator != (EnumInt<T> a, EnumInt<T> b) {
        if (object.Equals(a, null) && object.Equals(b, null))
            return false;

        else if (object.Equals(a, null) || object.Equals(b, null))
            return true;

        else
            return a.value != b.value;
    }

    public override bool Equals (object obj) {
        if (obj.GetType() != typeof(T))
            return false;

        EnumInt<T> id = obj as EnumInt<T>;
        if (object.Equals(id, null))
            return false;

        return id.value == this.value;
    }

猜你喜欢

转载自blog.csdn.net/ronintao/article/details/54019470
今日推荐