什么是一流的编程结构?

时间:2009-03-14 21:43:48

标签: .net

当尝试在C#中做一些相当先进的事情时(比如某种黑客攻击),提出了“头等”的概念。

例如,一个方法是第一类编程构造,因为你可以用它来做xyz(xyz不是方法所做的,但是一般的方法给你什么,我不记得xyz现在是什么),但是在.NET 1.1代理中无法传递给方法,因为它们不是一流的编程结构(我在这些行中读到了一些东西)。

一流的编程结构究竟是什么?

由于

6 个答案:

答案 0 :(得分:38)

编程语言中"first-class citizen" or "first-class element"的概念是由英国计算机科学家Christopher Strachey在20世纪60年代在一流函数的背景下引入的。 Gerald Jay Sussman和Harry Abelson可能在Structure and Interpretation of Computer Programs中提出了这一原则的最着名的表述:

  • 它们可能由变量命名。
  • 它们可以作为参数传递给程序。
  • 他们可能会作为程序结果退回。
  • 它们可能包含在数据结构中。

基本上,这意味着您可以使用编程语言中的所有其他元素完成所有编程语言元素。

答案 1 :(得分:22)

我怀疑你找不到正式的定义 Apparently Jörg W Mittag found one:)

鉴于正式的定义,我的答案的其余部分仅仅是我当时对它的理解。当然,每个使用术语“一流结构”的人是否完全相同都是另一回事。

判断某事物是否属于“第一类”构造的方法是问自己这样的事情:

  

是否支持此功能   与其他人完全融为一体   语言,还是有很多   不必要的限制   它的印象就是它   “狂奔”可能只是为了解决问题   一个特定用例,不考虑其他领域   该构造可能非常有用   如果它是更充分的“的一部分   语言“?

如你所见,这是一个明确的灰色区域:)

C#中的代表实际上就是一个很好的例子。在C#1中,可以将代理传递给方法,并且有很多方法可以将 很好地集成到语言中(比如可用的转换,事件处理,+ =和 - =转换为Delegate.Combine / Remove)。我会说他们一流的结构。但是,这与委托从C#2和3中获得极大的事实并不矛盾,使用匿名方法,隐式方法组转换,lambda表达式和协方差。他们现在可以说是更多的一流建筑......虽然我会说他们在C#1中是“头等舱”但我可以理解为什么有人会不同意。

IEnumerable可能会出现类似情况。在C#1.0中,foreach支持它,但foreach循环不会在最后处置IEnumerator。这部分是在C#1.2中修复的,但仍然只有消费 IEnumerable的语言支持, 没有创造它们。 C#2.0提供了迭代器块,这使得实现IEnumerable(及其通用等价物)变得微不足道。这是否意味着可迭代序列的概念不是C#1.0中的“第一类”构造?有争议的,基本上......

答案 2 :(得分:7)

  

一流的编程结构究竟是什么?

如果语言以类似于其他类型的对象的方式支持,则某些东西是一流的构造。

例如,在C ++中,函数不会被视为第一类构造:您可以在运行时创建其他类型的对象,但不能实例化新函数。相比之下,在C#3及更高版本中,函数可能会被认为是引入lambda / anonymous函数的第一类构造。

与许多其他事物一样,这自然是主观定义。维基百科有a good summary更具体的例子,C2也是如此。

答案 3 :(得分:1)

The C2 wiki has a good entry on first class language constructs.基本上,你不需要在语言中伪造它。

答案 4 :(得分:1)

我对一流编程结构的理解是,它意味着你可以以最好的方式完成 thing ,而不必做其他两件事,或者结合两三个其他概念。

因此,Java没有一流的闭包支持。我们可以通过构建一个类(使用另一个概念)来支持几乎所有使用闭包的东西,然后创建该类的实例(另一个概念)或匿名扩展该类( 又一个概念。)

与'functions'相同。在Java中你不能拥有函数,但是你可以使用静态方法,这些方法类似但仍然不同。

一个(不是我)也可以争辩说Java的泛型支持不是一流的,因为它是一个库黑客并且实际上不是“在”语言中。这意味着你可以在C#中用泛型做一些你无法用Java做的事情。

答案 5 :(得分:1)

什么是一流的编程结构?

简单回答:它支持语言提供的所有标准操作。在面向对象的语言中,正如您所料,第一类构造是对象。事实证明,在这些语言中,出于效率或遗留原因,通常存在二等公民,通常是原始数据类型,这些都不是适当的对象,并且您不能为此做某些事情。

例如,在Java中,Point是一个完整的对象。你可以宣布一个

List<Point> plist;

然后将分数加入其中。 int不是完整的对象。例如,有些东西你不能用它做一个int子类,或者除了一些预定义的运算符之外还要调用它上面的方法。你也不能把它存放在

List<int> intlist;

Java有一个问题,因为有一个“盒装”类型,Integer,它是一个完整的对象。例如,您可以声明List<Integer>。但是,使用Integer远比使用“int”效率低得多。 Java将Integer类型的自动装箱和拆箱(也就是说,转换)提供给int,并在需要其中一个或另一个的上下文中再次返回,以帮助程序员结合两者的优点。

对于整数,有两种类型 - 整数和整数 - 令人困惑,而且还有一些黑客攻击。我被告知,Java的早期版本没有原语,其所有类型都是完整的对象。事实证明这对于它的预期用途来说太慢了(当然,早期的Java无论如何都变得很慢!)因此添加了一些不支持正确对象语义的原语。

.NET 1.1委托中的

无法传递给方法,因为它们不是一流的编程结构(我从这些方面读到了一些东西)。

我对.NET一无所知,但似乎你有这个主意。你是对的 - 如果委托不能像任何其他标准对象那样传递给方法,它们就不是一流的编程结构。