.NET中的方法----操作符重载
.NET中的方法----操作符重载
CLR对操作符重载一无所知,它甚至不知道什么是操作符。是编程语言定义了每个操作符的含义,以及当这些特殊操作符号出现时,应该生成什么样的代码。尽管CLR对操作符一无所知,但是CLR确实规定了语言如何公开操作符重载,以便由另一种语言的代码使用。每种编程语言自行决定是否支持操作符重载,以及具体的语法是什么,编译代码时,编译器会生成一个标识操作符行为的方法。CLR规范要求操作符重载方法必须是public 和static方法。
例如:
public class MyComplex
{
public static MyComplex operator +(MyComplex c1, MyComplex c2) { }
}
编译器检查到源代码中出一个+操作符时,会检查是否有一个操作数的类型定义了一个名为op_Addition的specialname方法,而且该方法的参数兼容于操作数的类型。如果存在这样的一个方法,编译器就生成调用它的代码。如果不存在,就生成一个编译错误。
-
转换操作符重载
有时需要将对象从一个类型转换到另一个类型,当源类型和目标类型都是编译器的基元类型时,编译器自己知道如何生成转换对象所需的代码。如果源类型和目标类型不是基元类型,编译器会生成代码,要求CLR执行强制转换。在这种情况下,CLR只是检查源对象的类型和目标类型是否相同(是否继承)。而转换操作符重载可以自定义这一过程。
例如:
public class MyComplex
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
public class MyTest
{
public MyTest(MyComplex c)
{
}
public static implicit operator MyTest(MyComplex c)
{
return new MyTest(c);
}
}
static void Main(string[] args)
{
MyComplex c = new MyComplex()
{
Name = "test",
Age = 10
};
MyTest t = c;
}
为了真正理解操作符重载和转换操作符方法,强烈建议将System.Decimal类型作为一个典型来研究。
重要:事业能够一个转型表达式时,C#会生成代码来调用显式转换操作符方法。使用is或as操作符时,则永远不会调用这些方法。
-
扩展方法
扩展方法允许定义一个静态方法,并用实例方法的语义来调用它。
语法:public static 返回值 方法名(this 附加方法的类型 参数名,参数列表…)
C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符等。
扩展方法必须在非泛型的静态类中申明。
C#编译器查找静态类中定义的扩展方法时,要求这些静态类本身必须具有文件作用域(不能在嵌套类中定义)。
扩展方法有潜在的版本控制问题。如果目标类在新版本中增加和扩展方法相同签名的方法,则编译器在重新编译时会绑定到新的方法中,而不是扩展方法中。