# 类型安全

# 什么是类型安全?

类型安全,很大程度上,可以等价于内存安全。

类型安全的代码,不会试图访问自己没被授权的内存区域。

“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制;

有的时候,也用“类型安全”形容某个程序,判别的标准在于该程序是否隐含类型错误。

类型安全的编程语言与类型安全的程序之间,没有必然联系。

类型安全性意味着编译器将在编译时验证类型,如果尝试将错误的类型分配给变量,则抛出错误。一些简单的例子:// Fails, Trying to put an integer in a stringString one = 1;// Also fails.int foo = "bar";这也适用于方法参数,因为您要向它们传递显式类型:int AddTwoNumbers(int a, int b){    return a + b;}如果我尝试使用以下方式致电:int Sum = AddTwoNumbers(5, "5");编译器将引发错误,因为我传递的是字符串(“ 5”),并且期望使用整数。在一种宽松类型的语言(例如javascript)中,我可以执行以下操作:function AddTwoNumbers(a, b){    return a + b;}如果我这样称呼它:Sum = AddTwoNumbers(5, "5");Javascript自动将5转换为字符串,并返回“ 55”。这是由于javascript使用+号进行字符串连接。要使其具有类型意识,您需要执行以下操作:function AddTwoNumbers(a, b){    return Number(a) + Number(b);}或者,可能:function AddOnlyTwoNumbers(a, b){    if (isNaN(a) || isNaN(b))        return false;    return Number(a) + Number(b);}如果我这样称呼它:Sum = AddTwoNumbers(5, " dogs");Javascript自动将5转换为字符串,并将其附加,以返回“ 5条狗”。并非所有动态语言都像javascript一样宽容(实际上,动态语言并不隐式暗示使用松散类型的语言(请参阅Python)),其中一些实际上会在无效类型转换时给您带来运行时错误。尽管它很方便,但是它使您容易陷入很多错误,而这些错误只有通过测试正在运行的程序才能发现。就个人而言,我更愿意让编译器告诉我是否犯了这个错误。现在,回到C#...C#支持一种称为协方差的语言功能,这基本上意味着您可以将基本类型替换为子类型,而不会引起错误,例如: public class Foo : Bar { }在这里,我创建了一个新类(Foo),该类继承了Bar。我现在可以创建一个方法: void DoSomething(Bar myBar)并使用Foo或Bar作为参数来调用它,两者都将起作用而不会引起错误。之所以可行,是因为C#知道Bar的任何子类都将实现Bar的接口。但是,您不能做相反的事情:void DoSomething(Foo myFoo)在这种情况下,我无法将Bar传递给此方法,因为编译器不知道Bar实现Foo的接口。这是因为子类可以(并且通常会)与父类大不相同。当然,现在我已经走了很远,超出了原始问题的范围,但是所有这些都是好事:)

关于评论

评论前请填好“昵称”、“邮箱”这两栏内容,否则不会收到回复,谢谢!