57

我已经编写 C/C++ 代码近 20 年了,我知道 Perl、Python、PHP 和一些 Java,并且我正在自学 JavaScript。但我从未做过任何 .NET、VB 或 C# 的东西。托管代码到底是什么意思?

维基百科将其简单描述为

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

它特别指出Java(通常)是托管代码,所以

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

与此相类似,

  • .NET 是一种语言还是一种框架,这里的“框架”到底是什么意思?

好的,所以这不仅仅是一个问题,但对于像我一样长期从事该行业的人来说,我现在感觉相当 N00B-ish...

4

15 回答 15

38

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

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

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

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

于 2008-09-11T23:47:32.517 回答
13

我不认为只有您对 .Net 是什么感到困惑。已经有其他答案应该涵盖您,但我会为其他人提供这些信息。

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

在那里,您将看到特定于您安装的版本的文件夹。例如,如果您安装了 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 文件。运行它,它显然会吐出'hello world'。

显示 Console.WriteLine() 的行正在调用框架。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 平台之上编写代码的众多语言之一。Console.WriteLine() 的相同方法可以从 C#、VB.Net、Pascal、C++、Ruby、Python、F# 和任何其他在 .Net 平台上工作的语言调用。

我希望这会有所帮助。

-基思

于 2008-09-20T13:45:18.263 回答
11

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

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

于 2008-09-11T23:46:41.757 回答
10

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

于 2008-09-11T23:44:17.660 回答
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; }
}

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

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

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

于 2008-09-20T13:22:42.327 回答
3

托管一词通常仅适用于 .NET,因为 Microsoft 使用该术语。Microsoft 通常不使用术语“虚拟机”来指代 .NET 托管执行环境。

.NET 的“字节码”(IL) 与 Java 字节码有些不同,因为它被明确设计为在托管环境中执行之前编译为本机代码,而 Java 被设计为可解释的,但平台无关代码的概念类似。

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

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

于 2008-09-11T23:43:33.370 回答
3

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

于 2008-09-11T23:45:51.430 回答
3

冒着冒犯某些人的风险,我怀疑使用了托管这个词,因此他们可以使用非托管这个词而不是编译。虽然托管可能意味着更多,但现实情况是它似乎主要用于区分几乎即时编译的代码(作为曾经解释或 pcode 的替代)和本机编译代码。

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

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

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

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

于 2008-09-12T04:20:28.323 回答
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.
于 2008-09-20T13:43:09.140 回答
1

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

于 2008-09-11T23:44:19.750 回答
1

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

于 2008-09-11T23:45:48.653 回答
0

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

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

于 2008-09-11T23:42:37.460 回答
0

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

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

于 2008-09-11T23:48:20.597 回答
0

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

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

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

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

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

于 2008-10-08T19:04:44.973 回答
-1

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

于 2016-05-21T03:31:48.177 回答