关于c#:“托管”代码到底是什么?

关于c#:“托管”代码到底是什么?

What exactly is “managed” code?

我从事C / C ++代码已经有将近20年的时间了,而且我也了解Perl,Python,PHP和一些Java,并且我正在自学JavaScript。 但是我从来没有做过任何.NET,VB或C#的东西。 托管代码到底是什么意思?

维基百科将其简单描述为

Code that executes under the management of a virtual machine

它专门说Java是(通常)托管代码,因此

  • 为什么该术语似乎仅适用于C#/ .NET?
  • 您可以将C#编译为也包含VM的.exe,还是必须将其打包并提供给另一个.exe(la java)?

与此相类似,

  • 是.NET是语言还是框架,"框架"在这里到底是什么意思?

好的,所以这不只是一个问题,但是对于一个像我一样一直从事这个行业的人来说,我现在感觉有点像N00B ...


当您将C#代码编译为.exe时,它将被编译为通用中间语言(CIL)字节码。每当您运行CIL可执行文件时,它都会在Microsoft的公共语言运行时(CLR)虚拟机上执行。因此,不能,您的.NET可执行文件中不能包含VM。您必须在将要运行程序的任何客户端计算机上安装.NET运行时。

要回答第二个问题,.NET是一个框架,因为它是一组与语言无关的库,编译器和VM。因此,您可以使用C#,VB,C ++和任何其他具有.NET编译器的语言在.NET框架上进行编码。

https://bitbucket.org/brianritchie/wiki/wiki/.NET%20Languages

上面的页面列出了具有.NET版本的语言,以及指向其页面的链接。


我不认为您一个人对.Net是什么感到困惑。已经有其他答案应该让您解决,但我将为他人抛弃这些信息。

要查看" .net"真正是什么,只需转到c: Windows Microsoft.Net Framework

在其中,您会看到特定于已安装版本的文件夹。例如,如果已安装v2.0.xxxxx文件夹,则进入该文件夹。

在该文件夹中是框架。您基本上会看到一堆.exe文件和.dll文件。以System。*。dll开头的所有DLL文件本质上都是.Net框架。

您将在该文件夹中看到的.exe文件是开发人员和编译器的实用程序。您提到了C#。找到csc.exe文件。那就是你的C#编译器。

构建程序非常简单。将以下代码放入hello.cs文件中。

1
2
3
4
5
6
7
8
using System;
class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("hello world");
        }
    }

然后在命令行上键入> csc hello.cs

这将生成一个.exe文件。运行它,它将明显吐出" hello world"。

表示Console.WriteLine()的行正在调用Framework。 Console是驻留在System名称空间中的对象,而WriteLine()是静态方法。

这是该Console.WriteLine()方法的反汇编代码:

1
2
3
4
5
[HostProtection(SecurityAction.LinkDemand, UI=true)]
public static void WriteLine(string value)
{
    Out.WriteLine(value);
}

当人们说诸如"我应该使用PHP或.Net?"或"我应该使用Python或.Net"之类的东西时,您开始看到这是错误的讨论。他们显然正在将一种语言与一种框架进行比较。 C#是一种语言,它只是可用于在.Net平台上编写代码的众多语言之一。可以从C#,VB.Net,Pascal,C ++,Ruby,Python,F#和任何其他可以在.Net平台上运行的语言调用Console.WriteLine()的相同方法。

希望对您有所帮助。

-Keith


通常,它指的是您为您"管理"所有内存分配的事实。如果您使用的是托管代码,则不必担心在完成对象后释放对象。简单地允许它们超出范围将意味着VM最终将识别出不再有对其的引用,并且Garbage将对其进行收集以将内存返回给系统。

另一方面,除非您在丢弃引用之前显式释放指针,否则非托管代码只会"泄漏"。


它主要用于描述.NET,因为这是Microsoft选择将.NET与C / C ++和其他较旧语言区分开的术语。微软之所以选择它,是因为它不是与Java通常相关的术语,因为他们不想强调C#/。NET与Java之间的相似性(而不是称它为"虚拟机代码"之类的东西)听起来更像Java)。基本上,"托管代码"的使用是市场驱动的,而不是技术驱动的术语。


特别是在.NET和Visual C ++下,您可以同时具有非托管和托管代码。这些术语指的是分配和"管理"内存的方式。

非托管代码将是您惯用的C ++东西。动态内存分配和显式释放内存。 .NET运行时不为您管理内存,因此为"非托管"。

另一方面,托管代码由运行时管理。您在需要的地方分配内存(通过声明变量,而不是内存空间),然后运行时垃圾收集器确定何时不再需要它并对其进行清理。垃圾收集器还将移动内存以提高效率。运行时为您"管理"这一切。

如上所述,可以编写托管和非托管代码。

非网管:

1
2
3
4
5
6
7
class Bar : public Foo {
    private:
            int fubar;
    public:
            Bar(int i) : fubar(i) {}
            int * getFubar() { return * fubar; }
}

管理:

1
2
3
4
5
6
7
public ref class Bar :  public Foo
    private:
            int fubar;
    public:
            Bar(int i) : fubar(i) {}
            int ^ getFubar() { return ^ fubar; }
}

注意参考吗?这几乎可以指定一个Managed类。但是,当您将两种代码混合在一起时,它会变得非常混乱。例如,您想要将引用指针(^)的托管等效项保存到非托管类中的Picture Box控件。由于垃圾收集器可以移动内存,因此下次尝试取消引用图片框时,找不到该图片框。运行时不会告诉您的非托管代码其内存更改。

因此,您需要固定内存中的托管对象以允许您的非托管代码对其进行跟踪。然后是拆箱,还有其他各种古怪的东西,您可以将两者混在一起。代码复杂度巨大!

正式地,托管/非托管可能归结为.NET堆栈上代码的执行方式。但是,如果您来自c ++背景,我希望这与您更相关。


冒犯某些风险,我怀疑使用了托管一词,因此他们可以使用非托管一词而不是编译。尽管托管可能意味着更多,但实际情况似乎是,它通常用于在实时编译(作为曾经解释过的代码或pcode的替代品)和本机编译代码之间进行大部分区分。

或者换种方式,您更愿意使用:

a)可能会对系统造成不可控制的事情的非托管代码。

b)快速,可靠且接近操作系统的本机编译代码。

当然,它们实际上是同一回事。


托管意味着该代码不会编译为本机代码,因此可以在虚拟机的主持下运行。 Java编译为称为字节码的中间格式,Java VM知道该中间格式如何解释和执行。所有.NET语言都做类似的事情,编译为.NET运行时解释的IL(中间语言)。这有点令人困惑,因为.NET IL具有.dll和.exe文件结尾。


由于Microsoft使用术语"托管",因此通常仅将其应用于.NET。 Microsoft通常不将术语"虚拟机"用于.NET托管执行环境。

.NET的"字节码"(IL)与Java字节码有所不同,在于它明确设计为在托管环境中执行之前先编译为本机代码,而Java旨在进行解释,但是与平台无关的代码的概念很相似。

" .NET Framework"基本上是Microsoft提供的大量库,其中包含数千个可用于开发应用程序的类。

编译的C#.exe包含独立于平台的代码,可以在任何.NET兼容环境(包括Mono)中运行。但是,运行时通常与使用它的应用程序分开分发。


In a similar vein, is .NET a language or a framework, and what exactly does"framework" mean here? <<

.NET是Microsoft当前的企业软件平台。它包括:

?用于访问Windows功能的单个通用接口:

1
2
o The .NET Framework Class Library (FCL).
o The FCL provides a rich set of high-level functionality for developers.

?用于执行.NET应用程序的单一通用语言和运行时:

1
2
o Common Language Runtime (CLR) executes Common Intermediate Language (CIL).
o The CLR is God: it runs, controls, and polices everything.

?用于开发.NET应用程序的多种语言的选择:

1
2
o Every development language is compiled to CIL, which is run by the CLR.
o C# and VB are the two main development languages.

我可以回答框架问题。 .NET是一个框架,C#,VB.NET等是语言。基本上,.NET提供了一个通用的库平台来调用(所有系统... dll),任何使用.NET的语言都可以调用该库。所有.NET语言都被编译成MSIL(Microsoft中间语言,俗称IL),然后可以在装有适当.NET框架的任何PC上运行。


.NET是一个框架。公共语言运行时(CLR)执行在编译解决方案时生成的Microsoft中间语言(MSIL)代码(即,它不会编译为机器代码)。您不能在exe中包含API,因为它很大,您也不想包含。这里的主要好处是内存管理(在其他一些安全方面的优势以及可能我不知道的其他优势中)。


我个人认为"框架"一词有点用词不当。

.NET是一个"平台",由执行环境(CLR虚拟机)和一组库组成。它与Java或Perl或Python完全类似(没有一个曾被称为"框架")。

在大多数情况下,"框架"一词用于诸如Spring或Struts或QT之类的项目,这些项目位于像库这样的平台之上(即,不提供自己的执行环境)。

但是,与"库"不同,框架旨在重新定义基础平台的基本操作。 (Spring的依赖项注入违反了普通Java代码的构造函数调用逻辑。QT的信号和插槽实现拒绝了普通C ++代码。)

我知道我只是个书呆子,但是对我来说,.NET并不是一个框架。这是一个平台。


它可以引用由虚拟机而不是直接由CPU执行的任何代码。

我认为这可以实现垃圾收集和数组边界检查等功能。


.NET是一个框架。
它可以用于多种语言(VB.NET,C#,IronPython,boo等)

.NET始终按解释执行,并且不能在.exe中包含" VM"。任何希望运行.NET应用程序的用户都必须安装框架。


托管代码-MSIL和IL以及托管代码相同。当我们构建应用程序时,.dll或.exe文件在Bin文件夹中生成,这些文件称为托管代码。后来将这些文件提供给CLR生成本机OS可以理解的代码。


推荐阅读