究竟什么是“托管”代码?

时间:2008-09-11 23:38:58

标签: c# .net vb.net managed-code

我已经编写了近二十年的C / C ++代码,我也知道Perl,Python,PHP和一些Java,我自学JavaScript。但我从未做过任何.NET,VB或C#的东西。 托管代码究竟是什么意思?

维基百科describes it只是作为

  

在虚拟机管理下执行的代码

它具体说Java是(通常)托管代码,所以

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

以类似的方式,

  • 是.NET 语言框架,“框架”到底意味着什么?

好的,这不仅仅是一个问题,但对于那些曾经在我这个行业的人来说,我现在感觉很N00B-ish ...

15 个答案:

答案 0 :(得分:35)

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

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

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

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

答案 1 :(得分:10)

大多数情况下,它指的是所有内存分配都是为您“管理”的。如果您使用托管代码,则在完成对象后不必担心释放对象。简单地允许它们超出范围将意味着VM将最终识别出不再有对它们的任何引用,并且垃圾收集它们将内存返回到系统。

另一方面,非托管代码只会“泄漏”,除非您在丢弃引用之前明确释放指针。

答案 2 :(得分:10)

我不认为你对.Net是什么感到困惑。已经有其他答案可以覆盖你,但我会把这些信息丢给其他人。

要查看.Net“真的”只是转到c:\ Windows \ Microsoft.Net \ Framework

在那里,您将看到与您已安装的版本相关的文件夹。如果安装了v2.0.xxxxx文件夹,请进入v2.0.xxxxx文件夹。

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

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

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

using System;
class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("hello world");
        }
    }

然后在命令行类型> csc hello.cs

这会生成一个.exe文件。跑吧,显然会吐出'你好世界'。

表示Console.WriteLine()调用Framework的行。 Console是一个位于System命名空间内的对象,WriteLine()是一个静态方法。

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

[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

答案 3 :(得分:9)

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

答案 4 :(得分:6)

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

非托管代码将是您习惯的C ++内容。动态内存分配和显式释放内存。 .NET运行时不会为您管理内存,因此“不受管理”。

另一方面,托管代码由运行时管理。您可以根据需要分配内存(通过声明变量,而不是内存空间),运行时垃圾收集器确定何时不再需要它并清除它。垃圾收集器还将移动内存以提高效率。运行时“为你管理”它。

正如我上面提到的,可以编写托管和非托管的代码。

未管理:

class Bar : public Foo {
    private:
            int fubar;
    public:
            Bar(int i) : fubar(i) {}
            int * getFubar() { return * fubar; }
}

托管:

public ref class Bar :  public Foo
    private:
            int fubar;
    public:
            Bar(int i) : fubar(i) {}
            int ^ getFubar() { return ^ fubar; }
}

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

因此,您需要确定内存中的托管对象,以允许您的非托管代码跟踪它。然后是拆箱和各种其他怪癖,允许你混合这两个。代码复杂性是巨大的!

正式地,托管/非托管可能归结为代码在.NET堆栈上执行的方式。但是,如果你来自c ++背景,我希望这对你来说更有意义。

答案 5 :(得分:3)

术语托管通常仅适用于.NET,因为Microsoft使用该术语。 Microsoft通常不会在引用.NET托管执行环境时使用术语“虚拟机”。

.NET的“字节码”(IL)与Java字节码略有不同之处在于,它明确地设计为在托管环境中执行之前编译为本机代码,而Java旨在被解释,但平台的概念 - 独立代码类似。

“.NET Framework”基本上是Microsoft提供的一组庞大的库,包含数千个可用于开发应用程序的类。

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

答案 6 :(得分:3)

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

答案 7 :(得分:2)

冒着冒犯别人的风险,我怀疑使用了托管这个词,所以他们可以使用unmanaged而不是编译。虽然托管可能意味着更多,但实际情况似乎是用来区分主要是及时编译(作为曾经解释过的东西或pcode)和本机编译代码。

或换一种方式,您更喜欢使用它:

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

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

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

答案 8 :(得分:2)

  
    

类似地,.NET是一种语言或框架,“框架”到底意味着什么? <<

  

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

•用于访问Windows功能的单一通用界面:

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

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

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

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

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

答案 9 :(得分:1)

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

答案 10 :(得分:1)

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

答案 11 :(得分:0)

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

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

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

就个人而言,我认为“框架”这个词有点用词不当。

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

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

但与“库”不同,框架试图重新定义底层平台的基本操作。 (Spring的依赖注入违反了普通Java代码的构造函数调用逻辑.QT的信号和槽实现违反了普通的C ++代码。)

我知道我只是一个迂腐的混蛋,但对我来说,.NET不是一个框架。这是一个平台。

答案 14 :(得分:-1)

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