这是一篇简记,因此不做特别的排版
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;
}