什么是动态语言,为什么C#不符合要求?

32

在听一档播客时,我听到C#不是动态语言,而Ruby是。

什么是“动态语言”?动态语言的存在是否意味着有静态语言?

C#为什么是动态语言,还有哪些语言是动态的?如果C#不是动态的,为什么微软还在大力推广它?

同时,为什么大多数.NET程序员都对它着迷并离开其他语言转向C#?

为什么Ruby是“未来的语言”?


7
Ruby 未来的编程语言...拜托! - jasonco
4
@jasonco,我知道。Cobol是未来。 - JaredPar
19
LOLCODE 是未来! - Adam Robinson
3
未来唯一真正的语言是Lisp。它是唯一一个连续50多年被誉为未来语言的语言! - Pavel Minaev
为什么Ruby是“未来的语言”? - user
显示剩余3条评论
12个回答

74

什么是动态语言?

一个语言是否是动态的通常与编译器进行的绑定类型有关:静态或者晚期绑定。

静态绑定只意味着方法(或虚拟方法的方法层次结构)在编译时绑定。在运行时可能涉及到虚拟分派,但是方法标记在编译时被绑定。如果在编译时找不到合适的方法,则会收到错误提示。

相反,动态语言在运行时进行工作。它们在编译时很少检查方法的存在,而是在运行时完成所有操作。

为什么 C# 不是动态语言?

C# 在 4.0 版本之前是一种静态绑定的语言,因此不是一种动态语言。

为什么 Ruby 是未来的语言?

这个问题基于一个错误的前提,即存在一种语言是未来编程的选择。然而,目前并不存在这样的语言,因为没有一种单一的语言能够做到所有需要完成的不同类型的编程。

例如,Ruby 对于许多不同的应用程序都是一种很好的语言,比如 Web 开发是其中一种流行的应用。但我不会在 Ruby 中编写操作系统。


谢谢JaredPar,关于“为什么Ruby是未来的语言?”我在一个播客节目中听到过,那些人谈论它时好像这是事实。现在我知道他们错了... - egyamado
34
人们总是宣称某种语言是“未来的语言”,而这往往是他们最喜欢的语言。 - Chuck
请注意,没有什么可以阻止一种语言同时支持静态和动态类型。 Curl 就是这样一种语言。 - Christopher Barber
在播客节目中,有人说Ruby是“未来的语言”。那些从RoR转到.NET MVC的人可能会说Ruby是过去的语言。我还听说过一些Ruby开发人员说Ruby的创造是为了让开发人员感到快乐:)。关于这个主题有很多神话。 - angularrocks.com

26
在动态语言中,您可以这样做:
var something = 1;
something = "Foo";
something = {"Something", 5.5};
换句话说,类型不是静态的。在静态类型语言中,这将导致编译器错误。 像C、C++、C#和Java这样的语言是静态类型的。 像Ruby、Python和Javascript这样的语言是动态类型的。 此外,这与“强类型或弱类型”不同。那是完全不同的东西。

6

我惊叹于c#如何拥抱一组基本的编程范式。

我们可以说,c#允许丰富的面向对象编程、丰富的组件化编程、良好集成的函数式编程、完整的查询操作(linq)和不同类型数据源、通过pLinq和并行扩展实现优雅的并发编程,在下一个版本(c# 4.0)中将具有强大的动态功能,在c# 5.0中几乎肯定会有一组坚实的元编程特性。

我们只需要说c#在一个工具箱中整合了所有这些强大的东西。在我看来,这是必须的方式,因为从一种编程语言跳到另一种编程语言几乎总是非常痛苦的。


3

你知道VB6既可以是静态的,也可以是动态的吗?

如果你使用给定类型声明变量,那么你会得到静态行为:

Dim name as Label

现在您只能访问名称为 Label 的成员,智能感知已知道此情况。

如果您有一个类并添加了implements关键字,则您的类可以实现另一个类的方法。这是VB6允许的接口继承。您可以获得一些运行时多态性。

您还可以像这样声明变量:

Dim proxy As Object

现在智能感应不会提供任何帮助,而VB6将允许您对proxy进行任何操作:

proxy.foo()

这行代码可以嵌入到编译和运行的程序中,不会产生任何问题,特别是如果它本身没有被运行。只有当这行代码被执行时才会进行查找。

你还可以执行以下操作:

set proxy = <any instance>

这将会运行。无论任何<实例>是否有foo方法都没有关系。

然后,任何一个实现了foo的类的实例都可以被分配并调用该方法,VB6会顺利运行。

请注意,随着动态性的增加,运行时性能会有所下降。


3
C#是一种静态类型语言,这意味着你需要在编译时知道每个对象的类型。而在动态语言中,你不需要在编译时知道对象的类型。可能你会导入一些事先不知道的类,比如导入一个文件夹中的所有类,像插件之类的东西。或者甚至某个对象的类型取决于用户交互。
你可以通过使用接口或基类来实现类似的效果,但并不完全相同,因为你只能使用显式继承或实现该接口的类。
在动态类型语言中,它不关心你编译时的类型,它会尝试按照名称调用指定的方法,如果该方法不存在于该对象上,它将抛出运行时异常,因此程序员需要确保这不会发生或适当处理它。你在灵活性上获得了优势,但失去了一些编译时的错误检查。

3

维基百科条目可以看出,动态语言是指在运行时执行大多数编译时执行的操作。通常情况下,在动态语言中,变量可以快速轻松地更改类型,并且通常没有单独的编译步骤(而是解释执行或非常快速的编译)。C#是一种更传统的语言,使用变量声明并进行编译。

维基百科条目列出了许多动态语言。

另一方面,“X是未来的Y”意味着有人试图向您销售某些东西。(不一定是字面上的,但试图以方便发言者的方式影响您的信仰。)


3
“另一方面,‘X是未来的Y’意味着有人试图向你推销某物。” +1 很棒的评论。语言就像宗教一样…有很多种,因此没有一种最好的,未来也不会有一种最好的宗教。这毫无意义。 - jasonco

2

“静态”和“动态”这两个词并没有明确的定义。

然而,最常见的意思是两个问题:

1)在静态语言中,一个变量的类型(即变量可以包含或指向的值的类型)在程序执行期间不能改变。例如,在C#中,当您定义变量时,声明其类型,如下所示:

int a;

现在,a 只能持有一个 int 值 - 如果你试图将一个字符串赋值给它或调用一个方法,你会得到编译错误。
2)在静态语言中,对象的类型不能改变。在动态语言中,对象可以改变,因为你可以附加或删除方法和属性,从而基本上将其转换为完全不同的对象。

关于(1):这是显式与隐式的区别。有许多语言不需要声明变量的类型,但仍然是静态的,在编译时进行类型检查。这被称为类型推断。 - RHSeeger

2
在C#3.0中,所有内容的类型都需要在编译时知道。它是一种静态语言。动态语言使用运行时的动态分派来决定事物的类型以及对这些事物调用哪些方法。两种类型的语言都有其优缺点。C# 4.0将增加动态功能。Anders Hejlsberg在PDC上对静态语言和动态语言以及C# 4.0进行了精彩的讲解。 (点击此处观看)

1
哇,不是吧!静态类型是C#相比其他语言(如Ruby和PHP)最大的优势。拼写错误变成了编译时错误,而非奇怪的运行时不一致。我当然希望动态类型可以关闭。 - Jason Kester
@Jason:4.0中他们正在做的事情真的很棒。 "dynamic"成为声明动态类型的关键字,所以是可选的。 :) 但他们还添加了整个动态运行时层(“DLR”)。太棒了。视频也很好,因为Anders在最后谈到了4.0之后的一些东西。非常棒的东西。只有一个小剧透...C#中的REPL。 - JP Alioto

2
动态语言通常被认为是可以在运行时动态解释和生成代码的语言。C#无法做到这一点。
还有动态类型和静态类型语言。动态类型意味着变量的类型未设置并且可以在程序执行过程中更改。

很高兴见到有人知道动态语言和支持动态类型之间的区别。虽然我不确定C#是否是动态的 - 你肯定可以在运行时自我修改对象。 - Hamish Willee

1

C# 是一种静态类型语言,例如 int i = 0; 尝试将 i 设置为字符串,编译器会报错。

而 Python 中,一个用于保存整数的变量可以被设置为保存字符串。

静态类型:类型是固定的,动态类型:类型可以改变。

C# 正在尝试添加更多类似动态类型的特性,例如 var。


3
在C#中,"var"并不是一种动态特性,它只是隐式类型声明。变量的类型仍然是强类型的,不能更改。 - blowdart
在C#中,var只是为了节省打字而设计的简写。另外,动态语言不仅仅是动态类型,否则你可以使用object或者variant来存储所有的变量。 - Steven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接