.NET相对于Win32,能给我什么好处?

13

使用.NET相较于Win32,我会得到什么好处?有时候我可以通过搜索50-100行代码来重用它们,那么.NET给我带来的价值在哪里呢?

我自从Win32出现以来就一直在开发它(超过15年)。虽然有时候需要调用更多的函数,当然你需要跟踪句柄等,但它非常直观且非常稳健。我们的应用程序(250,000行代码)安装时间不到1分钟,并且极少出现任何兼容性问题。

我关注了SO上关于.NET与Win32的讨论(例如Win32 vs .Net),但它们没有回答这个问题。

14个回答

24
答案很简单:更高层次的抽象和与幕后“真实”事物的解耦。这就是为什么.NET可以在其他操作系统上实现。
事实上,即使没有.NET也是可能的,但不太实用。举个简单例子:.NET中的WCF提供了一流的IPC和SOA框架,每个人都可以使用。它是内置功能。在win32中,你会得到同样的自编码,但需要使用第三方库或其他东西。用户群体很小,没有那么大的社区支持你解决问题,而且难以实现。 .NET Framework可以让你直接拥有这些功能。
对于大量的应用程序,.NET将加快开发时间并降低开发成本。
对于特定类型的应用程序,情况则相反。例如,使用.NET几乎不可能开发实时应用程序,因为第二级GC会冻结所有线程。
补充说明:
.NET Framework 4.5包括一个增强版垃圾收集器。它为服务器垃圾收集器启用了多线程后台垃圾收集(在app.config文件中使用<gcServer>元素启用),不会冻结应用程序线程。
不幸的是,Mono垃圾收集器还没有那么先进,所以基本陈述对于Mono仍然是正确的。

4
这就是为什么.NET可以在其他操作系统上实现。如何拼写"mono"? - elcuco
3
好的:IS已在其他操作系统上实现,如Linux(使用Mono)。 - Thomas Maierhofer
2
Win32也在其他操作系统上实现了:请参见Wine(www.winehq.org)。 - Chris Smith
2
酒...那个非模拟器的测试套件只在两台计算机上100%成功运行,而且没有人知道为什么,不是吗? - flq

15

仅我个人认为,只有从事Win32开发超过15年的人才能称其为简单且强大。如果你愿意自己编写整个250,000行代码而不是使用组件,那么你的应用程序将很容易安装。但我不确定这种权衡一定值得。

.NET带给你的是更快的开发速度,出于各种原因。更高层次的抽象、优秀的组件可以轻松集成、没有指针问题、较少需要管理自己的内存或句柄。如果您已经从事Win32开发15年了,也许您不需要这些任何东西。但是,您是否曾经招聘过新的初级程序员呢?我确信他们会比学习Win32更快地学习.NET。在你甚至能说出“Hello world”之前,Win32中有太多需要学习的内容。


6
相信我,这 250,000 行代码中几乎没有与 Windows API 相关的内容。可能只有约 1,000 行,大约占总代码量的 10% 左右,但不会更多。 - RED SOFT ADAIR
1
我认为学习.NET不会比Win32更快,但会更有效率。.NET并不容易学习。C#是一门复杂的语言,特别是自3.0版本以来(Lambda表达式,LINQ等)。但是,如果你掌握了这些知识,就可以用优雅和直接的方式编写无法在C++中编写的代码。 - Thomas Maierhofer
4
不需要管理自己的内存或句柄是不正确的,您仍然需要管理资源(如套接字、数据库连接等需要及时释放),并且仍然可能出现内存泄漏:http://www.codeproject.com/KB/showcase/IfOnlyWedUsedANTSProfiler.aspx - rpg
3
@MarkJ: 或许不像你想的那样重要。许多 LINQ 技巧都可以用 C++ 中的 STL 实现,有时甚至更加灵活。至于指针,它们几乎可以被避免使用。引用、智能指针和 STL 容器意味着你通常并不需要指针。但这仍然是一个合理的观点。.NET 的一个重要优点与 Win32 并没有太大关系。它提供了编写应用程序其余部分所需的语言和一般库类的访问权限。 - jalf
3
我不认为C#比C++更难。想想函数指针、指向指针和其他C++语言特性,这些都不容易理解。 - Jason Evans
显示剩余5条评论

6

在转向ASP.NET / ASP.NET MVC进行Web开发之前,我已经使用C ++开发游戏约8年。从我的角度来看,使用.NET而不是本地C ++代码时,以下是最重要的优点:

  • 非常好的IDE工具。 Resharper可以比VisualAssist做更多的事情
  • 不再有无效/空指针错误或泄漏内存问题
  • 坚实的运行时,具有比Win32更好的API
  • 许多出色的开源.NET库,比我能找到的C ++库更多(即使没有C#Boost)
  • 由于Mono的存在,将软件移植到另一个平台比使用C ++更容易

8
在像C#或Java这样的托管语言中,内存泄漏已经成为过去式的错误观念是错误的。 实际上,在这些语言中创建内存泄漏相当容易。 垃圾回收器并不能消除在应用程序中检查内存泄漏的必要性。它只是删除某些类型的内存泄漏。 在这些语言中,通过持有引用的静态对象、不必要的引用、缓存等仍然经常出现内存泄漏。 - nkr1pt
7
@nkr1pt,尽管在.Net中容易出现内存泄漏,但在C ++中仍然比.Net更容易出现内存泄漏,并且跟踪非托管泄漏也更加困难。 - Pop Catalin
7
程序不仅仅管理内存,还有其他未受控制的资源。你确定能正确使用和实现IDisposable模式吗?你知道背后发生了什么吗?你真的知道GC.SuppressFinalize()方法是干什么并且如何使用它吗?如果你不使用它,你知道会发生什么吗?实际上,在.NET中未受控制的资源更难处理,因为C++程序员使用与内存相同的模式。未受控制的资源会消耗大量受控内存的优势,你必须同时关心两者。 - Thomas Maierhofer
4
GC通过避免需要明确的所有权,实现了根本上更加清晰的API设计。未受管理的资源并不是一个大问题——因为你几乎从不需要它们(而当你需要时,几乎总能找到预包装的托管包装器)。它并不能解决所有问题,但认为它由于“其他未受管理的资源”而无关紧要是荒谬的。 - Eamon Nerbonne
4
首先,Win32是用C编写的,而不是C++,尽管它可以轻松地从C++中调用。有几个质量更高的封装器在其上面,其中之一是.NET。其次,在C#中您可能会遇到空引用错误,也可能会出现内存和资源泄漏等问题。第三,在C++中有比C#更多的库可用:考虑一下,一个拥有30年历史的语言与一个只有8年历史的语言相比。最后但并非最不重要的是,您不能在Mono和.NET上运行完全相同的代码库,因为1.它们正在分化2.Mono仍然受到专利不确定性和平台不成熟的限制。 - rpg
显示剩余10条评论

6
易于使用。并且与.NET框架的其余部分(非Win32相关部分)易于互操作。
.NET没有什么神奇的,它只是一个用于轻松完成常见任务的预定义类的巨大集合。其中许多任务都是诸如“创建窗口”或其他Win32功能之类的东西。
至于Win32是否“直接和强大”,我不这么认为。
以下是一个很好的例子:程序员需要的最基本的功能之一:检索与刚刚发生的错误相关联的错误消息:

http://msdn.microsoft.com/en-us/library/ms679351%28VS.85%29.aspx

  • 7个参数
  • 需要阅读两个表格以了解这些参数
  • 需要考虑安全性注意事项
  • 必须调用特殊的、具体的函数(LocalFree)来释放系统分配的缓冲区。

仅为实现这么简单的功能?这就是“直截了当”的吗?

Win32 API 是设计最糟糕、最复杂和难以正确使用的 API 之一。它唯一能够做到的一致性就是使易于理解的用法变得错误,并要求大量的操作才能实现正确性。

但当然,任何花费十年时间与 API 工作的人都已经面对过这些问题并习惯了它们。对你来说可能没有问题。而且更好的是,既然你已经有了应用程序,你可以继续使用它。没有理由将其丢弃并从头开始使用 .NET。

但是,如果今天你要从头开始启动一个项目,那么

  • 在.NET中,学习曲线会更加友好(但是如果你已经掌握了技能,这就不太重要了)
  • .NET中错误的范围会减少(更难以以“错误”的方式调用函数,即使出现问题,也会有更少的负面影响)
  • 更容易找到新的程序员加入您的团队
  • 大多数人在像C#这样的语言中比在C或C++中更加高效。 .NET提供的主要功能之一是使用.NET语言。相比之下,类库可以被认为是锦上添花。

我还记得有一次我想把打印模式从纵向改为横向,结果却遇到了很多问题。这是一个非常具有挑战性的学习经历。(上一个人只是将东西侧着打印以避免这种情况,但当我们本地化到日语时,这种方法并不完全奏效。) - David Thornley

6

如果你觉得它有用,而我从来没有。 - Nemanja Trifunovic
垃圾回收可以节省大量时间,编写一个完全无漏内存管理系统,并简化编写异常安全代码的过程。但有经验的C++程序员可以处理这个问题。这并不像所有人说的那么重要。几乎没有.NET程序员知道幕后发生了什么。如其他帖子所述,程序还必须处理内存以外的其他资源。对于所谓的“非托管资源”,垃圾回收是无法帮助你的。它会让生活变得更加困难。你知道如何正确实现IDisposable接口吗?你知道什么是抑制finalize吗? - Thomas Maierhofer

2
WinAPI是用于与Windows进行最底层交互的工具,覆盖了Windows操作系统向用户提供的所有功能。
.Net是一个框架、一个运行时环境和一个大型库集合,用于不同目的并抽象了Windows API。它基本上提供了隐藏Windows API的面向对象抽象。
如果您使用.Net,则仍然可以透明地使用WinAPI,并且如果选择通过PInvoke直接使用WinAPI。
选择.Net还是WinAPI取决于您要构建的应用程序类型。如果是与Shell强烈集成的应用程序,则使用WinAPI;如果不需要但需要使用强大的XML、连接性(WCF)、图形(WPF)或数据访问(ADO.Net、Linq)库,并且需要.Net提供的生产力提升,并且在一定程度上牺牲一些灵活性(需要确保.Net在目标计算机上运行,这已经不是什么大问题了),则选择.Net。

2

.NET本身实际上是围绕Win32 API构建的,因此在原则上,您可以使用Win32 API做任何.NET可以做的事情。.NET的优点在于开发的便捷性 - 这也意味着更快的交付和更少的错误。.NET的调试能力也要好得多。

.NET的安装和运行速度并不是什么大问题。您可以用任何语言编写糟糕的软件,就像您可以用任何语言编写良好的软件一样。在.NET中有不同的技巧和窍门,而C ++中则有不同的技巧和窍门(所以这肯定需要学习曲线),但最终两者都同样出色。

我甚至听说过一个传言,即一个良好编写的C#程序实际上可能比一个等效的C++程序更快,因为JIT编译器可以针对特定的CPU优化汇编代码,而C++优化器只能进行通用优化。不过我不知道这是否属实。

.NET软件的兼容性也与C ++类似。一方面,它需要安装.NET框架,但另一方面,由于强名称和GAC,不再存在DLL地狱的问题。而且许多东西已经在默认安装中了,而您通常需要在C++中使用第三方库(如XML解析,DB连接性,SOAP web服务,RPC等)。我认为这是平衡的,并且.NET可执行文件的较小尺寸肯定是一个优点。


有很多事情在普通的.NET中是无法完成的,必须使用PInvoke才能实现。 - user47322
这是正确的,但它们中的大多数很少被使用。编写一些PInvoke签名也不难。 - Vilx-

2

如果不了解你的应用程序性质,很难回答这个问题。如果它是一个典型的内部业务应用程序,需要大量的数据库访问和报告生成,我会说.NET提供了很多优势。但如果它是游戏、图像处理或者一般面向广泛客户群体销售的产品,我建议使用Win32。


1

.NET让你能够使用真实的语言编写Sql Server存储过程。试着在Win32 DLL中做到这一点。


2
为什么有人会想要这样做呢?(可能有一个有效的理由,但我不知道是什么...) - Wim ten Brink
2
嘿,不要问我为什么你首先想要存储过程。它们在源代码版本控制中很麻烦。至少 .Net 存储过程具有合理的语法,不需要 20-30 个参数,并且具有良好的调试环境。 - MSalters
哈哈,好答案! :-) 我不太喜欢存储过程,因为它会将业务逻辑添加到数据层中。这感觉就不对。 :-) - Wim ten Brink
当您需要验证数百万条记录时,您真的想将它们往返于应用服务器吗?每件事都有其时间和地点。 - Matthew Whited
我曾经需要验证50,000条需要插入的记录。我与DBA合作解决了这个问题。在Delphi中,我可以在两分钟内完成大约80%的所有验证。然后将数据发送到SQL中的存储过程,花费了一个多小时来验证剩下的20%数据。所以,是的,有时我会想在应用程序中完成这个操作。(尽管一百万条记录可能有点太多。) - Wim ten Brink

0

除了你已经提到的观点之外...

  • .NET 平台依赖性较小(在 mono 下,它可以在 Windows、Linux、OS X、BSD 等系统上运行)
  • 你可以使用 VB、C#、C++ 等语言编写 .NET 代码,并且可以将不同语言编写的模块无痛地协同工作。

实际上,我认为你会发现 .NET 包装了很多 win32 功能。


4
在生产环境中,你不应该完全依赖于Mono,因为它是一个开源项目,用于将.NET应用程序移植到类UNIX系统上。 然而,Microsoft并没有正式支持它,但它得到了Novell的赞助,后者近来与微软密切合作。 - nkr1pt
3
Mono是一个非常强大和有用的环境,在我看来,你可以依赖它。 - abatishchev
2
完全没有依赖于Mono“因为它是一个开源项目”是毫无意义的。 - Eamon Nerbonne
1
@MSalters:你真的相信 Mono 只需要一个程序员就能支持吗? - MarkJ
1
专有的、闭源的应用程序存在的问题在于,当它们变得不盈利时,它们可能会被关闭,或者公司可能会倒闭,而你没有任何救济措施。在开源项目中,通常会有一个用户社区,如果所有维护人员失去兴趣,他们可以聚集起来做些什么。有一些商业应用程序我不相信它们明年还能存在,而有些开源应用程序将长期存在。 - David Thornley
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接