一起谈.NET技术,.NET框架:为什么我们要尽量使用框架内建的功能,而不是重新发明

简介:   有很多人经常会持有这样的疑问:为什么 .NET 框架要把一些很简单的功能也封装起来?而有些人所坚持的“有现成的就用现成的”的习惯在那些“明明只是很简单的功能却被封装了起来”的情况下也显得很可笑。那么,实际上到底有没有必要用那些本来就很简单的封装?这些简单的封装到底具有什么样的意义呢?  其实大部分这样的简单的封装都是针对“跨平台使用”而设计的。

  有很多人经常会持有这样的疑问:为什么 .NET 框架要把一些很简单的功能也封装起来?而有些人所坚持的“有现成的就用现成的”的习惯在那些“明明只是很简单的功能却被封装了起来”的情况下也显得很可笑。那么,实际上到底有没有必要用那些本来就很简单的封装?这些简单的封装到底具有什么样的意义呢?

  其实大部分这样的简单的封装都是针对“跨平台使用”而设计的。有些人可能会说:.NET 框架有什么跨平台可言?其实 .NET 框架虽然现在只提供 Windows 上的版本,但其它平台上的 CLI 实现,如 Mono、DotGNU 等等也都有赖于 .NET 框架和 CLI 的预见性方能成为现实;而可以在多种环境中使用的 RIA 平台 Silverlight 也是将这种思想发挥到了极致。

  举个例子来说,.NET 框架中 IPAddress 类型具有 NetworkToHostOrder 和 HostToNetworkOrder 方法,如果你使用 Reflector 来查看反编译后的代码,你会发现 NetworkToHostOrder 只是调用了 HostToNetworkOrder,而 HostToNetworkOrder 的原理也只不过是一些简单的位移运算而已。

  有的人看到这里可能会想:包了两层方法性能多差啊,用到它的地方自己写位移运算不是也可以么?不要这样做。实际上,CLR 的 JIT 编译功能会把简单的方法进行内联编译,所以像是 NetworkToHostOrder 这样的方法在进行 JIT 编译之后结果和直接使用位移运算并没有区别,而在这里偏执地直接使用位移运算,不仅性能没有实质上的提升,还会导致代码难以维护;而且这样的代码如果到了使用 Big-Endian 字节序的计算机上,就不能用了!

  当然了,如果你善于使用预编译指令之类的工具,这种问题也自然难不倒你。

  与此相似的,还有:有些具有 Visual Basic 5/6 编程经验的人在使用 Win32API 的时候会习惯使用 Long 或者 Int32 来当作各种 Handle 的等价类型,然而这样做是错的!如果你去查看 SDK 中关于 HANDLE 的定义,你会发现:

typedef PVOID HANDLE;

  也就是说,实际上在 64 位程序里,Handle 和指针一样,是 64 位的——虽然绝大部分情况下这 64 位的 Handle 只有低 32 位有效,但是数据类型本身需要的 64 位空间不能忽视。所以实际上在需要用到任何类型的 Handle 的场所,都应该使用 IntPtr,而非 Visual Basic 中的 Long 或者 CLR 中的 Int32,这样才能保证代码在 IA-64、x86-64 硬件平台上正常运行。

  而最为有用,又最为复杂,以致于很多人不愿意去了解的,则是关于“低锁定技术”的各种封装。例如,ReaderWriterLock(Slim)、Lazy<T>、ConcurrentDictionary<TKey, TValue>等等。由于这些封装的内部实现实在是很复杂,不管是从篇幅上考虑还是从笔者我的能力上去考虑,想详细、深入地去解释实在是不现实,所以这里只能介绍一下大致上的原理了。

  低锁定技术是一种由来已久的设计方式,有兴趣的人可以在网络上自行搜索相关的资料。低锁定技术的大致思路就是:对于没有初始化的值,在第一次读取的时候需要锁定并将之初始化;一经初始化之后,进行读取时不需要任何锁定操作。

不过尽管低锁定看上去是个很聪明的做法,可实际实现起来却要考虑很多问题,因此也有很多文章警告过,不要尝试实现低锁定,因为实际上是会产生意外的。

实际上 CPU 可能会按照一定的模式来优化内存操作,改变某些读、写操作的顺序;又或者是因为读取了已经缓存的数据而导致了判断失误,致使同一时间尝试进行访问的其它线程读取到了错误的数据,结果采用低锁定技术的程序却发生了异常。

关于这个问题,想要了解细节的同学可以参考这些文章:http://msdn.microsoft.com/en-us/magazine/cc163715.aspxhttp://www.ibm.com/developerworks/cn/java/j-dcl.htmlhttp://msdn.microsoft.com/en-us/library/ff650316.aspxhttp://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

  尽管这样的问题也可以通过精密的设计而解决,但如果你使用过 C/C++ 并且知道 MemoryBarrier 的概念,你也可以发现下面这些东西:

#ifdef _AMD64_
#define MemoryBarrier __faststorefence
#endif
#ifdef _IA64_
#define MemoryBarrier __mf
#endif
// x86
FORCEINLINE
VOID
MemoryBarrier (
    VOID
    )
{
    LONG Barrier;
    __asm {
        xchg Barrier, eax
    }
}

  这也说明在不同的平台上,由内存模型或其它技术细节上的差异所导致的问题,具体的解决办法也是各不相同的。而对于我们一般的应用程序开发人员来说,要想全面掌握这些解决办法,并且在每个必要的场合准确无误地采取合适的办法也是相当困难的。

  其实这样繁琐的问题本来就不应该让一般应用程序开发人员去面对,而是应该让 .NET 框架之类的靠近底层的设施去解决。所以对于使用 C/C++ 的开发人员来说,当他们用到 MemoryBarrier 的时候,并不需要真的根据目标平台而写入实际的操作代码,只需要插入相应的 MACRO 就可以了。

  而实际上,.NET 框架也把这一部分隐藏了起来,在 MSDN 博客上有博文解释了在 CLR 中实现了一种正确的内存操作模型(链接:http://blogs.msdn.com/b/cbrumme/archive/2003/05/17/51445.aspx),而且无论哪种平台上的 .NET 框架(或者其等价物)都会保证它们的行为一致;同时 .NET 框架中提供的诸如 Lazy<T>、ConcurrentDictionary<TKey, TValue> 等类型,也有助于避免由于对内存模型不了解(比方说,你知道使用 lock 时是不是应该同时使用 MemoryBarrier 或者 Volatile 吗?又或者,你知道应该在什么时候使用、什么时候不需要使用吗?),或者一时间的逻辑误区而写出了存在潜在问题、导致程序不稳定的代码的情形发生。

  总地来说,除非是对底层的技术细节具有相当高的程度的了解,并且具有极强的信心可以解决任何问题……否则还是“有现成的就用现成的”比较好,因为这样做的话 .NET 框架会为你解决好那些恼人的跨平台兼容性问题。

目录
相关文章
|
9天前
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
22 3
|
9天前
|
开发框架 安全 Java
.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力
本文深入探讨了.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力。.NET不仅支持跨平台开发,具备出色的安全性和稳定性,还能与多种技术无缝集成,为企业级应用提供全面支持。
20 3
|
13天前
|
消息中间件 监控 数据可视化
基于.NET开源、功能强大且灵活的工作流引擎框架
基于.NET开源、功能强大且灵活的工作流引擎框架
|
13天前
|
人工智能 开发框架 前端开发
C#/.NET/.NET Core技术前沿周刊 | 第 12 期(2024年11.01-11.10)
C#/.NET/.NET Core技术前沿周刊 | 第 12 期(2024年11.01-11.10)
|
12天前
|
人工智能 开发框架 安全
C#/.NET/.NET Core技术前沿周刊 | 第 13 期(2024年11.11-11.17)
C#/.NET/.NET Core技术前沿周刊 | 第 13 期(2024年11.11-11.17)
|
12天前
|
XML 开发框架 .NET
.NET 9 中 LINQ 新增功能实操
.NET 9 中 LINQ 新增功能实操
|
13天前
|
网络协议 Unix Linux
精选2款C#/.NET开源且功能强大的网络通信框架
精选2款C#/.NET开源且功能强大的网络通信框架
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
43 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
63 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
49 0

热门文章

最新文章

相关课程

更多
下一篇
无影云桌面