MSDN 访谈录之C#编程一

HALCON实战:用两个工业相机实现无缝大视野拼接(附完整代码与避坑指南) 本文详细介绍了使用HALCON软件实现双工业相机图像无缝拼接的完整解决方案,涵盖硬件配置、相机标定、坐标系转换和图像拼接等关键步骤。通过高精度标定和矩阵变换技术,可构建大视野检测系统,适用于液晶面板、PCB等工业检测场景,显著提升检测效率和精度。 阅读详情

MSDN 访谈录(MSDN Show)
 
 C#编程

C#是一种令人耳目一新且为之一振的编程语言,它设计给C++程序员带来快速的开发能力,而又不牺牲C和 C++所特有的功能和控制。
    在今天的这一期里,我们将要和Anders Hejlsberg交谈,他是微软一位资深的工程师,一直帮助设计、开发和实现该语言,并发挥其在未来.NET平台中的作用。我们还要和Jeffrey Richter(著名的编程作家和咨询专家)交谈,他从事C#的工作已经一年有余了。

 

 

介绍


Robert Hess,微软产品经理和“Show”节目主持人。

ROBERT HESS: 让我们继续关注理解.NET体系(Architecture)。我们今天将关注新的C#(念“C Sharp”而不是“C Pound”!)编程语言。首先看看MSDN 消息更新栏目。

 

 

MSDN 消息更新


由技术编辑Erica Wiechers主持
(略去与C#无关的谈话)

 


技术闲聊(TECHNO BABBLE )


Robert Hess和资深工程师Anders Hejlsberg会面,要讨论…???

 


ROBERT HESS: 欢迎回到这个栏目。好了,就象任何一个要在其上面开发软件的平台,为了使这些应用软件能真正地运行起来,所需要的一个主要东西就是一种编程语言。目前,.NET已经拥有了一种专门为此开发的专用语言,我们称之为C#。今天和我们在一起的是Anders Hejlsberg,他是微软一位资深的工程师,在C#语言以及.NET平台领域都扮演了一个关键的角色,在以前的“show”节目里大家都见过他。所以我邀请他到这里来,和大家一起谈论C#,谈谈它是什么,有了它程序员就可以从中得到什么好处,以及它是怎样真正地影响到应用程序的开发的。

那么,您究竟从事C#哪方面的研究工作,是从什么时候开始的?


ANDERS HEJLSBERG: 在最近大概两年半的时间里,我们一直在从事C#的研究工作。设计小组由4人组成,而且在这段时间里,我把主要的精力都放在了这上面。要知道,对于一种新的编程语言,我们有许多事情要去做。我想首先也许就是为程序员提供方便,使程序员开发出更多的产品就是最终目标。如今,虽然在产品的收益方面仅仅只是初具规模,但可以说,我们的目标,在某种意义上,不但要使C#具有C++强大的功能和出色的表现,而且还要使其具备简单易用以及RAD(Rapid Application Development,快速的应用程序开发)语言的生产率。

我们已经做了一些工作,例如,涉及到程序员如何利用更好的工具编写组件的范畴。如果你看看我们是怎样写应用程序的,应该是曾经怎样写应用程序的,如果回顾过去,也就是说5年或10年以前,应用程序就是这样铁板一块地被创建的,它和操作系统的唯一交互,你知道,就是进行文件的i/o操作,而且无论如何操作系统都会载入应用程序,接着用户就与其交互,最后退出。看看现在我们是如何创建internet应用程序的,相比起来简直是天壤之别。应用程序不再是铁板一块了,而是由一系列更小的组件构成,它们分别栖息于不同的环境。例如,你可能拥有类似存储过程(stored procedures)和SQL Server那样的组件,也可能拥有栖息于浏览器中的控件,或者是存在于ASP网页中的代码。商业对象生存于中间层,调用整个集合的组件就等于调用该应用程序。于是为了使……


ROBERT HESS: 而当时您明白其中的每一个组件都比5或10年前的一个应用程序更加复杂。


ANDERS HEJLSBERG: 噢,绝对,绝对。同样,为了减少创建组件的复杂性,不象那种大块头程序,每当必须创建其中的一个组件时,就不必另起炉灶,而应该尽量继承一些早已存在于这些专门的栖息环境(hosting environment)中的东西。如果要写浏览器中的一个控件,就要继承一个基控件;如果要写中间层的一个商业对象,就要继承某些商业对象类;而要想公开属性、方法和事件等等,就要说明它们是如何通过把属性与组件联系一起,以便与栖息环境相结合。而且还要能够为这些组件撰写随组件一起发布的文档。


ROBERT HESS: 所有的这些只是标准的面向对象的编程,Smalltalk 拥有此特性的时间似乎已经不短了,并且……

 

ANDERS HEJLSBERG: 嗯,绝对如此,现在并不是不能做这样的事。但如果注意一下这种今天已经得到了广泛应用的编程语言,它们实际上并不真正支持面向组件的概念。如果你当初同意我们什么时候谈论组件,那么认为它们具有属性、方法和事件在当今是极其平常的。但如果注意一下C++,就会发现它仅仅提到“方法”这个概念,没有属性,也没有事件。现在,你可以利用命名模式来仿真它们,也就是说,对于一个属性,可以用一个get color和一个set color的方法来取代一个color属性;而要代替类中作为第一个类成员的事件,你拥有的用于接收事件的接口就应该被实现,为了这样,你就必须处理一些琐碎的事……

 

ROBERT HESS:嗯,部分原因是由于C++是基于C的,它只是象预处理程那样,又由于C本来就不支持,C++也不支持……

 

ANDERS HEJLSBERG: 是的,实际上我多少认为,你所看到的就是从C到C++再到C#的发展过程。从C到C++,面向对象编程的概念被加进去了。如果你经历了从C++到C#,那么我会说,面向组件编程的概念也已经被加进去了,而它们之间真的存在着某些相似的地方。就象可以用C代替C++进行面向对象的编程,你也可以用C++代替C#进行面向组件的编程,只不过是更困难而已。用C来进行面向对象的编程是极其困难的,你必须手工地布置V表(虚拟函数表),并且还要处理所有琐碎的事情。用C++写组件也确实可行,但必须要为属性手工地设置命名模式(naming patterns),必须实现事件同步(event syncs),必须具有外部的IDL文件,在文件中可以对栖息属性(hosting attributes)进行描述,必须具有外部的文档文件,等等。我们只真正采纳了其次一个合理的步骤,它反映了人们是如何编写应用程序并把其整合到语言中的


ROBERT HESS: 那么,最初的一些目标是什么?仅出自内心的看法,当您第一次着手这个项目时,您要解决的问题和要确定的这种新语言的方向是什么?


ANDERS HEJLSBERG: 嗯,我认为正如您所说,面向组件只是一方面。我想另一个关键的因素就是简单化。使编写应用程序更加简单化,不让程序员做一些琐碎的事,机器可以代你做。大量的简化取决于.NET runtime本身,但也取决于语言。基本上,最终我们所做的,就是让你把更多的时间、更多的精力放在算法上,而让系统去做一些琐碎的事。我认为,许多其它非常关键的事情比较现实,我总不能吩咐人们把他们现有的代码通通扔掉吧。我们必须找到权衡的方法,并不仅仅是你的编程技巧,而且还包括你以前编写的、早已存在的代码。因此在C#里,以权衡你技巧的名义,我们努力坚持在与C++的基础语法最接近、最真实的地方。所以用了C#,C++程序员会立即觉得很眼熟、很亲切。


ROBERT HESS: 您的所做的一切应当以C语言为基础,是否就是当初的思路之一?或者您是否原来就认为,让我们应与过去彻底决裂,再开始设计一种全新的语言?

 

ANDERS HEJLSBERG: 嗯,我想这种语言应该以一种崭新的面貌出现,可是我们明白,必须让C和C++程序员熟悉这种语言。当然那就意味着在某种程度上,我们必须把语句结构从弯曲的大括号变换成其它一些东西。我们已经打下了一些基础,但仍然存在着其它某些关键的规则,譬如允许写健壮的软件,这就意味着象垃圾回收(garbage collection)、异常处理、类型安全这样的功能,根本地改变了设计该语言的思路,非常难于上手,以后也不容易扩展。我的意思是说,在C++中,C++语言拥有的一个强大功能之一,但有时也同样是难点之一,事实上您知道,就是没有类型安全。如果你了解清楚自己要做什么,就会从中获取巨大的力量,否则,只是自找苦吃。在C++中,获得一个虚悬指针(dangling pointer)易如反掌。同样,覆盖掉一个数组的尾部,或者拥有一个未初始化的变量等等,也是极其容易事情。而我们需要解决这些难题。我认为,我们不能只从 C++着手并扩展它。而真的必须以退为进,以C++的灵魂设计出新的方案,而这些我们已经差不多完成了。

 

ROBERT HESS: 那么其它语言呢?您注意到这些语言在做了什么吗?是否它们就是Pascal 或 Modular 2 或 FORTH,您从中得到什么借鉴?


 ANDERS HEJLSBERG: 绝对!噢,我们考虑到,嗯,我的意思是说,我本人出身于深厚的Pascal背景,所以,自然要考虑到Pascal, Modula, Oberon, 要考虑到Smalltalk,Java,C++以及所有的语言。要知道,今天它们能生存下来并得到了应用,且或多或少地传播开了。

 

ROBERT HESS: 您觉得这些语言的哪些功能比C和C++表现得更出色?而您就可在新的语言中引进这些功能?

 

ANDERS HEJLSBERG: 嗯,我认为有一件事可以说明,我总是喜欢Smalltalk,就是因为在该语言中,任何东西都是对象。这使程序得到了大大的简化,因为无论拥有什么样的数据片,都可以把它当作一个对象从A点搬到B点。一般来说,任何东西都可以对其进行操作。可以把它当作对象类型,放在容器中。在Smalltalk实际的实现过程中,如果这样做的话,程序性能的额外负担(overhead)就会大大加重。例如,在Smalltalk中,当运算float数字时,每生成一个新的数字,如当1.0和2.0加到一起时,就要分配一个含有3.0值的新对象。而这样做,代价当然是非常昂贵的。如今在C#中,我们已经进行了一些革新工作,使你获得了同一样的利益,而却没有额外负担。只要把float当成float,或者是double就把它当成double使用,就没有什么代价。但如果把它们视为对象(也仅当这样做时),就得给它们分配堆(heap)。因此,就形成了样相当完美的统一体,既能给您大量的好处,而又没有程序性能的额外负担。


ROBERT HESS:C#生成的最终结果的某些结构到底如何?您得到了一个C#程序的文本文件并且编译它,那么编译器本身存在着些什么问题,如何设计这些方案以便在使用时更具效率,而这种优化其它语言有可能已经做过,而甚至最终还要生成二进可执行文件吗?


ANDERS HEJLSBERG:嗯,我们已经做了一些涉及到如何编码的工作。假如你是一个C++程序员,当然熟悉怎么做,在C++中声明和实现是分开的。所以所有声明都放在H文件里,接着在另一些模块中把它包含进去(# include),然后再在CPP文件中写出实现程序。在C#中,把它们都写在同一个地方。这样,可在那里写出声明接着又立即写出实现代码。


ROBERT HESS:假如您必须在另外一些文件中采用在main文件中声明的某些值,那又怎么办?

 

ANDERS HEJLSBERG:那么会出现什么情况呢?当编译时,实际生成的代码或重新生成的输出文件都含有两种代码:元数据(metadata),符号表(symbol tables)或其它相关的符号信息(symbolic information),而不是仅生成只含有可执行代码的X86机器码。在某种意义上,这些代码变成了自我描述。所以当想从一个代码片使用另一代码片时,只要引用它们便可,而这些代码的自我描述足以让人们知道在那里有什么类,类拥有什么成员,可以调用什么方法,属性是什么以及类型名是什么,等等。


ROBERT HESS:那么,是不是象您所指的.OBJ文件或.EXE文件,抑或……


ANDERS HEJLSBERG:嗯,您说的很对,我们在.NET中使用的格式就是PE格式,故可以指向另外的EXE或DLL。我们现在调用这些汇编程序,并基本上用这种语言大量地描述这些高级DLL,它们不仅含有代码,也含有这样的信息:说明什么在代码中,以及这些代码真正地引用了其它什么样的汇编程序。


ROBERT HESS:您所说的代码是指二进制代码或可执行代码。


ANDERS HEJLSBERG:嗯,实际上,我们并不直接生成可执行的X86机器码,而是生成MSIL,也就是中间语言,它由.NET定义,并由JIT(实时编译器)编译。

 

ROBERT HESS: Ok,这样看来,您拥有了一个可执行文件,其本身与中间语言以及元数据相关联,而如果我想要在其中一个应用程序里使用它,我只要指向它并说道,嘿,我要借用这些类,借用这些对象,并在这样的程序中使用它。这使我想起了许多人曾经提过的一个问题,涉及到中间语言存在着潜在的漏洞,有些人可能会攫取这种文件并对其进行反编译,然后再恢复成当初的源代码。因此,并非所有的智能特性(intellectual property)都有利于开发者。这方面还有什么问题?


ANDERS HEJLSBERG:嗯,首先,您现在实际上可以用DLL进行处理。这可能有点难,但您可以采用包含X86码的一个DLL,然后至少把它反编译成汇编程序。您可做同样的……


ROBERT HESS:在我的Apple II上,我一直都是这样做的。

 

ANDERS HEJLSBERG: 确实如此,我对此感到惭愧。但是运用.NET DLL并把其反编译成MSIL,也可以做相同的工作。它们并不能直接地被反编译成C#,尽管您也有可能蒙对,但太难了。不同的地方在于,有着非常多的符号信息(symbolic information)关联到由C#生成的代码,以及MSIL,对不起,是.NET汇编程序。例如,你可以从代码中得知,什么类在这里,它们的成员是什么,等等。这是一个需要解决的棘手问题,因为让代码自我描述(self describing)的好处多多,但事实上代码对自己进行的描述,也同样使反编译工具所处理的代码变得似乎容易理解了。如果我们认识到这个问题,基本上我们要做的,就是创建一个称作搅拌机(obfuscator)的东西,它会加入并搞乱代码,使代码变得几乎难于看懂,可仍然保留着原来相同的公共接口。


ROBERT HESS:是的,因为您遇到这样的难题:当采用、编写这些编译器程序时,就想让编译器理解代码(或类似的过程等),但却不想让人们在同一层次上看懂它们。


ANDERS HEJLSBERG:确实如此,确实如此。我确实想指出,对于一个小程序,实际上可以对其进行反编译,给出足够的时间和资源,你甚至可理解它在干什么。然而对于真实世界中的一个应用程序,这却是一项艰巨的任务。在现实中你最好运行这个应用程序,理解它在干什么,然后写出它的一个copy。你会很快达到这个水平的。


ROBERT HESS:或许写出一个更牛的程序,因为您是一个更牛的程序员,对吗?为了断定我们的观众是否想要着手实现下一个C#项目,他们需要去理解有关C#的一些什么问题?


ANDERS HEJLSBERG:嗯,我想首先你必须考虑到自己的基础。如果你有现成的代码体,让我们假定它是用C++写成的吧,也许把这些代码移植到.NET framework的最佳途径就是使用Managed C++,该C++编译器随.NET一起发布。然而,如果你着眼于编写新的代码,也就是写新模块、更大的模块,加入到一个应用程序或一个完全了解的应用程序中,而且你精通C++,那么我建议考虑C#。


ROBERT HESS:因此,我们没有必要说,每个人都必须用C#重写他们的应用程序。我们在说,人们必须了解他们目前所从事的工程的类型,是否是一个现成的项目、陈旧代码,并且有时还要用C#写一些组件,莫非您可以交替地使用C#和C++?


ANDERS HEJLSBERG:噢,绝对。首先,如果你拥有现成的代码,假定这些代码是由Windows平台所支持的任何一种语言写成的,则把它们编译成COM组件或DLL,就会获得与这些代码很强的交互操作能力(interoperability)。如果要写专门用于.NET framework的代码,用于.NET framework的新代码,当然要用.NET framework所支持的任何语言写。我们计划在Visual Studio .NET中发布四种语言:C#、 C++、 Visual Basic 和 Jscript。可是为了与产业界和学术界合作,我认为,最新的统计可能不是很准确,但我想总共大约17种不同的语言现在都瞄向了这一个平台,其范围一直从APL到Cobol。


ROBERT HESS:那么象Fortran又怎么样呢?


ANDERS HEJLSBERG:我相信相关的工作正在进行中,可我不能准确地知道到底谁正在设计Fortran编译器。但关键的是,实际上我们已经做了多次示范了,你可以在C#中写一个基类,并在C++中继承它,然后再用VB程序创建它的一个实体。在不同的语言之间进行的互用操作是无缝的。我想正是这些性能,使.NET framework甩开产业界中其它竞争对手的产品。(有兴趣的读者可以到http://www.lahey.com/net_down.htm去下载
Lahey/Fujitsu Fortran for .NET Technology Preview 1,译注)


ROBERT HESS:而且它采用并允许在基础层次上进行多语言的互用操作。


ANDERS HEJLSBERG:是的,很准确。不过是位于一个很高的层次。您可能会争辩:现在的语言可以进行互用操作,但只能位于很低的层次,例如,DLL的入口点、具有指针在其中的结构,等等。而我们正在谈论到更高的语义层次,是位于面向对象的层次,具有类和接口等等。


ROBERT HESS:C#被认为是微软的私有语言吗?


ANDERS HEJLSBERG:其实并非如此。我们与产业伙伴特别是HP和Intel合作,今年年初,我们向一个叫做ECMA(欧洲计算机制造商协会)的欧洲标准化组织提交了建议,以便标准化C#和CLI。 CLI代表通用语言基层体系(Common Language Infrastructure)。


ROBERT HESS:而这是不是有点类似于C Runtime 和VB Runtime?

 

ANDERS HEJLSBERG:嗯,实际上CLI是.NET framework的一个大的子集。在某种意义上,它是.NET可以移植到其它平台的那部分。这意味着,例如,它不包括任何Windows专门的UI库,因为其它平台对此并没有多大的兴趣。


ROBERT HESS:就象内存管理,而且……

 

ANDERS HEJLSBERG:嗯,绝对如此,内存管理,大部份的类库被包含在CLI中。我们于9月份向ECMA提交了这个建议,并在一次ECMA会议上得到了采用,制订这两个标准的工作正在进行中。其中一个是C#标准,而另一个是CLI标准。


ROBERT HESS:那么,C#具有ECMA标准又意味着什么?


ANDERS HEJLSBERG:嗯,这意味着其它产业伙伴们可以也最有可能在不同的平台上实现该语言。


ROBERT HESS:如果我是类似波音这样的公司,且拥有一些老式的PDP 11/70计算机,我想让C#在其上面运行,可能会考虑利用ECMA标准给这些老掉牙的家伙设计编译器,如果没有什么人已经做了类似工作的话。

 

ANDERS HEJLSBERG:绝对正确。现在这两个标准实际上已相继被提交,而目前C#本身并没有规定一个runtime库,而是依赖于.NET framework,或者,当我们正在谈论到标准提议时,C#依赖于通用语言基层体系为其提供的runtime基层体系和类库。我们目前正在与标准化组织以及我们的产业伙伴们共同研究,以确定最低的门槛。很明显,CLI将被分成几个层次,事实上我们向ECMA提交的方案被分为几个层次,这些层次开始于很低的核心层,而你真正地拥有了这些核心数据类型,一些象数组那样十分简单的东西,以及在那里的所有原子变量(atoms),但是分子(molecules)就不必要了。它们被构建在更高层的栈上,因此对于嵌入设备也是这样,实际上可以把其应用于一个非常轻量级的环境(lightweight environment),而这种轻量级环境可以移植到不同的平台。

 

ROBERT HESS:因而我可以让C#的一个版本在我的手表中或某些类似的设备中运行。

 

ANDERS HEJLSBERG:是的,理论上是这样,或在您的冰箱中,或任何需要的地方。

ROBERT HESS:在某种程度上,这就是.NET framework的全部目标,也就是允许编程的基层体系存在于多种不同类型的设备中,通过网络或蓝牙等类似连接,一个设备就可以和另一个设备通讯,并且借用服务,提供相互支持,

 

ANDERS HEJLSBERG:对,那是其中的一部分。我想,现在我们应当牢记于心,尽管您谈论到了分布式应用程序或者设备之间的相互通讯,但安置在.NET framework甚至是在CLI中的基层体系,实际上并不要求在网络的两端都有.NET存在。而且,我们所推荐的体系结构确实具有引导作用,何时利用类库来设计程序完全基于XML和SOAP这样的产业标准,并且也可以在Linux box(比方说Java和Apache web server)中实现它,然后利用其它工具在另一端开发相应的程序,如果你乐意的话。

 

ROBERT HESS:因此在我的C#应用程序里,假如我正在编写它与一个外部服务连接,就可以视其为标准的C#调用,而运行于不同的机器上的一个外部服务可能是Amazon.com,或者类似于其它一些既不运行Windows也不运行C#的系统……

ANDERS HEJLSBERG:这正是所有web服务的梦想……

ROBERT HESS:而所有要做的事情就只有实现SOAP了。

 

ANDERS HEJLSBERG:是的,嗯,基本上我们所要做的是利用现有的internet的基层体系,意思是,传输协议是http,有效承载(payload)是以XML格式封装的SOAP(SOAP formatted XML),并且实际上在网络的另一端可以是任何东西。当从C#中访问XML和SOAP的调用时,我们事实上有能力使它们看起来象具有方法的对象,但是我们给你提供了所有的基层体系,通过在.NET framework中所具有的所有连续的基层体系,你便可以把方法调用转换进XML SOAP包中,这样的包可以穿越网络并回传然后再解包。

ROBERT HESS:好了,您说您从事C#的工作至今已经几年了,而XML的生命期也恰好与此相同。这就意味着当它们开始时,彼此之间是毫无了解的。

ANDERS HEJLSBERG:嗯,XML的历史可能要长一点。SOAP却相当新,它与C#还有.NET framework是齐头并进的,并且我们也非常积极地从W3C引进这些标准化主体,我们一直在跟踪它的发展,并把这些技术追加到最新的标准中。

ROBERT HESS:那么SOAP和XML之间在这一层次上的相互连接性(interconnectivity)是否当初就是C#一个方面的内容,或者是随着该语言的发展而发展的?

ANDERS HEJLSBERG:嗯,我认为这里确实存在着一些距离。大部分需要处理XML和SOAP的基层体系是由.NET framework而不是C#提供的。C#语言建立在.NET framework的顶层,并使您具有访问这些东西的权力,例如,通过我们在C#中称之为属性(attribute)的东西,在代码中就可以直接表达什么东西正由这个类的实体映射(mapping)成为穿越internet的XML格式。所以我可以说,例如对于成员(field),我想使这个成员变成具有同样名字的XML元素,让这个类名变成XML里的标签(tag)名,等等。而且属性可以直接地集成到代码里,这就是使XML 和 C#变得更易于使用的措施之一。

ROBERT HESS:那么它们真的很合适在一起?

ANDERS HEJLSBERG: 是的,确实如此。

ROBERT HESS:当考虑一个应用程序的设计时,为了更好地运用C#,我想要有条有理地建立应用程序,有没有什么不同的办法?或者还是与正常地开发一个C应用程序具有相同的思路?

 

ANDERS HEJLSBERG:嗯,我认为关其中的一个关键原则就是,您是以一种很深的面向对象的方式进行编程的,甚至当您在使用C#时,是以一种面向组件的方式进行的。所以会趋向于认为您的应用程序设计有点区别。好,如果您正在使用C++,就可能会想到写对象等等。当您用C#写程序时,例如您可能会想到,哎呀,我正在写一个组件吗?嗯,这个组件必须能加入到Visual Studios的工具栏,以便我可以把它拖到表单,或拖到一个商业对象,或拖到一个网页,然后它是不是会被属性检查器(property inspector)显示出来,哎呀,那么在那里我到底应该拥有什么属性,我怎么控制下拉单里的东西,我能不能拥有那样的编辑器?现在,我们把基层体系的所有东西都呈现给您,它使您认识到您的设计不同于C++传统的设计。

 

ROBERT HESS:因此很多时候,您仍然在编写应用程序,通过装点修饰应用程序,您正好有更多的性能要展示。

ANDERS HEJLSBERG:是的,您可以这么说。

ROBERT HESS: 有关更多此类面向服务的完整概念是什么呢?因此我正在编写一个几乎无GUI的应用程序并且运行在一台服务器上,并计划用一个web客户程序对其进行攻击。客户程序请求首先到达服务器并要求回应以便跟踪包(package)等类似的东西。这是否从根本上改变了思路,或者仍然是同样的服务方向?

ANDERS HEJLSBERG:嗯,我认为在某种意义上,它让您多一点地考虑应用程序中的抽象。您应更加注意认识到,我是怎样把应用程序安置到商业逻辑层(business logic tier)和表示层(presentation tier),是怎样把API放到商业逻辑层,以便它既可以被表示逻辑用来表示HTML或基于UI的客户,甚至也为遍布网上的Web服务指明入口点(entry points)。因此,您应注意一点,再也不能编写那些铁板一块的程序了。

 

ROBERT HESS:您是否想象这本身有助于人们利用他人的组件比过去更容易?我记得在波音公司工作时,我们老是遇到有关代码重用这个关键问题。我们必须确保所编写的任何应用程序、任何代码都是专为代码重用而设计的,虽然这听起来在理论上确实是一个伟大的主意,但在实践中,却由于从来没有得到好好的利用而寿终正寝了,因为重用别人的代码简直是难上加难。您认为这样居然能使代码重用更容易吗?

 

ANDERS HEJLSBERG:我认为会的,这里起关键作用的实际上就是.NET framework。事实我们已经定义了这样一个底层(substrate),在其之上可以生成组件。而说到许多关于如何把它们装入类中,如何使它们成为组件,我们给您明确的指导,而事实上整个framework都当作其中一个范例,但关键是组件一律要能被各种各样的语言所访问,因此这里您已经谈论过这个问题,例如,如果某些家伙在用Cobol编写一些语言或库而您却想从C++中利用它们,您知道,这会特别困难。实际上我们提供给您一个substrate,让您进行上述交互性操作。所以您大有希望使组件交互操作。因为事实上令人感到困惑的是,组件是以不同的设计观点或在不同的抽象层上编写而成的,这正是使人们糊涂之处。他们并不习惯于这种风格的API,因此迷失在基层体系之中,只见树木不见森林,您应该明白我的意思。因此通过说明许多关于如何写组件,并且提供了用于写组件的永久有效的API和基层体系,您就极其有希望获得更好的重用性

ROBERT HESS:嗯,我认为解释恰到好处。为了能抓住C#语言体系的重点,您认为最后还有什么重要的概念要让观众去理解?

 

ANDERS HEJLSBERG:我想最好的方法就是您应亲自摆弄它。所以我会催促人们从我的站点下载,而我也相信您会给他们地址的。下载它,摆弄摆弄,写出一些例子,参加我们的用户组或新闻组,和其他用过它的人交谈,看看他们有什么经验。我想你会过得很舒心的。

ROBERT HESS:我肯定会在本记录稿的后面建立一个链接,以让他们下载当前版本的C# runtime以及我们在PDC上公开的.NET材料,我猜我们会有另一个版本的……

ANDERS HEJLSBERG:我们的beta 1.0版要发布了……

ROBERT HESS: Beta 1.0版很快就要发布了,因此您提到的新闻组里也要建立一个连接到beta 1.0的链接。因此您应保证寄给我的email里要含有这些新闻组,以便我能建立。

ANDERS HEJLSBERG: 好的。

ROBERT HESS:谢谢Anders,感谢您的谈话,而且我希望观众感谢这位真正帮助过设计C#语言的专家,感谢他有关开发应用程序的心得。

    在短暂的休息之后,我们会继续与一位程序员交谈,至今他用C#开发应用程序已经有些时日了,我们会了解到他对这种语言的想法,以及任何有助于我们用C#开发自己应用程序的线索。所以请不要走开哦。

MATLAB 设置legend加标题 x1 = linspace(0,5); y1 = sin(x1/2); plot(x1,y1) hold on x2 = [0 1 2 3 4 5]; y2 = [0.2 0.3 0.6 1 0.7 0.6]; scatter(x2,y2,'filled') hold off legend({'sin(x/2)','2016'},'Location','northwest','Orientation','horizontal')%水平 legend添加标题 lgd = legend; lgd.Fon 阅读详情

相关推荐

ZYNQ出现问题及解决办法汇总(一直更新)

问题目录使用软件及开发板版本一,vitis在build project时卡住。二,Could not find FPGA device on the board for connection 'Local'三,FPGA configuration failed:DONE PIN is not high四,Could not find ARM device on the board for connection 'Local' 使用软件及开发板版本 开发板:MZ7XA-7020 软件:vitis2020.2(

qq_45057368的博客 1万+

msdn 访谈录之C#编程二

<!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--><script type="text/javascript"

zgqtxwd的专栏 438

Allegro规则管理器实战:5步搞定Xnet等长组设置(含Relative Propagation Delay配置)

本文详细介绍了在Cadence Allegro规则管理器中,通过5个实战步骤高效设置Xnet等长组的方法。核心内容包括创建Xnet属性、定义引脚对、建立匹配组,并重点讲解了Relative Propagation Delay规则的配置与应用,帮助PCB设计师确保高速信号时序对齐,提升系统稳定性与性能。

weixin_29193259的博客 516

MSDN 访谈录之C#编程一 (转)

MSDN 访谈录之C#编程一 (转)[@more@]MSDN 访谈录(MSDN Show)C#编程XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:...

csd3176的博客 122

手把手教你绕过网易易盾验证码:滑块、点选、语序全攻略

本文深度解析了以网易易盾为代表的现代验证码技术,重点探讨了滑块、点选、语序及空间推理等交互式验证码的工作原理与对抗策略。文章从行为验证和空间推理的核心逻辑出发,剖析了验证码交互的数据流与关键参数,并提供了模拟人类行为轨迹、维护设备指纹等工程实践方法,旨在帮助开发者在合规前提下设计更健壮的自动化流程。

3c4x5z6v7b的博客 690

S型速度曲线进阶:基于Sin²(x)的PLC平滑运动控制实践(以伺服/步进系统为例)

本文深入探讨了基于Sin²(x)的S型速度曲线在PLC平滑运动控制中的实践应用,特别针对伺服/步进系统。通过对比传统梯形曲线和七段S曲线,详细展示了Sin²(x)曲线在加速度连续性、计算效率和参数自适应性方面的优势,并结合博图平台的具体实现技巧和实战案例,为精密运动控制提供了优化方案。

weixin_28718793的博客 242

MSDN 访谈录(MSDN Show)C#编程

MSDN 访谈录(MSDN Show) C#编程 C#是一种令人耳目一新且为之一振的编程语言,它设计给C++程序员带来快速的开发能力,而又不牺牲C和 C++所特有的功能和控制。 在今天的这一期里,我们将要和Anders Hejlsberg交谈,他是微软一位资深的工程师,一直帮助设计、开发和实现该语言,并发挥其在未来.NET平台中的作用。我们还要和Jef...

angang6606的博客 179

顶刊《会计研究》数据复现|最新上市公司数智化数据

本文基于Python文本分析方法构建了中国A股上市公司数智化指标(1991-2024),通过识别年报中的"机器学习""智能医疗"等关键词,量化企业数字化与智能化融合程度。研究发现数智化企业更倾向于非正式渠道的定性披露以规避风险,该指标为监管完善信披规则提供了参考。研究还揭示了数智化对企业信息披露策略的转变,并提出了未来研究方向,包括数智化对绿色创新、ESG表现等影响机制。数据覆盖非金融类上市公司,采用文本挖掘技术构建结构化指标,为相关领域研究提供了微观基础。

PPdata_Academy的博客 1487

msdn 访谈录之C#编程二 JEFFREY RICHTER

程序员天地 Robert Hess和Jeffrey Richter(著名的编程作家、专栏作家和咨询专家)的谈话。 ROBERT HESS: 欢迎回来。我们正要涉及到有关C#编程方面的问题。为了有助于我们理解这些问题,我邀请我的好朋友Jeffery Richter到这里来。Jeffery恰好是一名撰写了很多编程书籍的程序员,他最新的一本书为Programming S...

angang6606的博客 239

BurpSuit在不同浏览器中配置代理

文章通过分享各大浏览器如何设置代理的知识,帮助初学者快速掌握代理配置相关技能。

北冥同学的成长记录笔记 1万+

最新Python爬虫实战(入门爬虫篇)——案例17:某天气网40天天气预报数据采集(详细爬虫思路截图+抓包动图演示+完整爬虫代码+详细注释)

本次案例通过分析某天气网的数据接口,成功实现了对40天天气预报数据的批量采集。抓包分析:利用浏览器开发者工具找到隐藏的JSONP数据接口,掌握URL构成规律。请求模拟:构造带有Referer和User-Agent的请求头,添加时间戳参数避免缓存,获取原始数据。数据解析:处理JSONP格式,去除前缀后使用json模块解析,提取所需字段并规范化日期格式。数据存储:利用pandas将结构化数据保存为Excel文件,便于后续分析和使用。动态数据接口的发现与分析JSONP数据的清洗与解析。

努力让自己发光,对的人才能迎着光而来 22万+

[翻译] Anders Hejlsberg访谈录——Geek of the Week

[翻译] Anders Hejlsberg访谈录——Geek of the Week 原文地址:http://www.simple-talk.com/opinion/geek-of-the-week/anders-hejlsberg-geek-of-the-week/ 原作者:Richard Morris 译文地址:http://www.cnblogs.com/AndersLi...

weixin_34290631的博客 213

6、基于深度强化学习的无人机路径规划

本文研究了基于深度强化学习的无人机路径规划方法,提出了一种融合改进DQN算法与人工势场法的路径规划策略。通过设计合理的网络结构、状态空间、动作空间和奖励函数,结合ε-贪心策略进行动作选择,实现了无人机在复杂环境中的自主避障与目标导向飞行。仿真实验表明,该方法具有收敛速度快、实时性强和可操作性高等优点,能有效完成室内环境下的路径规划任务。文章还总结了算法优势,并对未来在连续动作、复杂环境适应及多无人机协同等方面的发展方向进行了展望。

web39explorer的博客 166

<<展现C#>> 第二章 NGWS Runtime 技术基础(修订)

                   第二章  NGWS  runtime 技术基础     既然你已经具有了C#全面的印象,我也想让你领略NGWS runtime的全貌。C#依靠由NGWS提供的运行时;因此,有必要知道运行时如何工作,以及它背后所蕴含的概念。    所以,这一章分为两部分——它们是所有的概念和应用的基础。两部分的内容虽然有些重叠,但有助于加深理解正在学习的

rainbow的专栏 2131

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

“扫雷”游戏的幕后

    介绍    曾想了解“扫雷”游戏在幕后所发生的一切吗?嗯,我想过,还由此决定对其进行了研究。本文是我的研究结果,现公之于众。 主要概念1. 使用 P/Invoke 调用 Win32 API。2. 直接读取另一个进程的内存。注1:本文的第一部分包括一些汇编代码,如果你不是很明白,无关要紧,这不是本文的目的,你尽可以跳过不管。然而,如果你想问我有

rainbow的专栏 1935

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

<展现 C#> 第一章 C#简介(修订)

                            第一章  C#简介     欢迎你加入C#(念C sharp)的世界! 这一章将让你了解C#,并回答一些相关的问题,如:你为什么要使用C#,C++和C#主要有什么不同的地方,以及为什么C#使软件开发更容易而且还更有趣。1.1 为什么是另外一种编程语言?    你必须回答的一个问题:当已经使用C++或VB从事企业开发时,为

rainbow的专栏 1829

<<展现C#>> 第八章 用C#写组件(修订)

第八章    用C#写组件 这一章关于用C#写组件。你学到如何写一个组件,如何编译它,且如何在一个客户程序中使用它。更深入一步是运用名字空间来组织你的应用程序。这章由两个主要大节构成:。你的第一个组件。使用名字空间工作 8.1  你的第一个组件 到目前为止,在本书中提到的例子都是在同一个应用程序中直接使用一个类。类和它的使用者被包含在同一个执行文件中。现在我们

rainbow的专栏 1632

<<展现C#>>第四章 C#类型(修订)

 第四章        C#类型     既然你已经知道如何创建一个简单的C#程序,那么我将会给你介绍C#的类型系统。在这一章中,你学到如何使用不同的值和引用类型,加框和消框机制能为你作些什么。尽管这一章的并不侧重于例子,但你还可以学到很多重要的、关于如何使用现成类型创建程序的知识。4.1 值类型 各种值类型总是含有相应该类型的一个值。C#迫使你初始化变量才能使用它们进行

rainbow的专栏 1585

<<展现C#>>第六章 控制语句(修订)

                                  第六章   控制语句      有一种语句,你在每种编程语言控制流程语句中都可以找到。在这一章中,我介绍C#的控制语句,它们分为两个主要部分:。选择语句。循环语句如果你是C或C++程序员,很多信息会让你感到似曾相似;但是,你必须知道它们还存在着一些差异。  6.1 选择语句    当运

rainbow的专栏 1559

<<展现C#>> 第五章 类(修订)

 第五章  类      前一章讨论了数据类型和它们的用法。现在我们转移到C#中至关重要的结构——类。没有了类,就连简单的C#程序都不能编译。这一章假定你知道了一个类的基本组成部分:方法、属性、构造函数和析构函数。 C#在其中增加了索引和事件。      在这一章中,你学到下列有关类的话题。      。 使用构造函数和析构函数      。给类写方法      。给一个类增加属性存取标志   

rainbow的专栏 1504
上一篇: msdn 访谈录之C#编程二
下一篇: “扫雷”游戏的幕后
rainbow
博客等级 码龄27年 3粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值