C#.NET编程的特点

重新看下.NET的特点,细节之处以C#为准。

基本特点

.NET一般用来代指【.NET Framework】,但严格的说.NET是一种设计,【.NET Framework】是其在Windows上的实现API,而【.NET Core】是其跨平台实现的API。

.NET中的【托管代码ManagedCode】是基于各个版本的【.NET API】编写的代码。

【托管代码ManagedCode】在手动编译后,会被编译为【中间语言IL】。

.NET中的【托管代码】具有与具体语言无关的特点,无论是是使用C#还是VB,还是C++,还是F#编写的程序,只要基于【.NET API】,都会被编译为【中间语言IL】。

与【.NET API】对应的runtime被称为【公共语言运行时CLR】-----大概是为了强调多种语言共用这一特点所以叫公共xxxxx。

在程序初次运行的时候,【公共语言运行时CLR】会启用【实时编译JIT--Just In Time】将【中间语言IL】编译为机器码,并且会进行【自动垃圾回收】。

---------------------------------------------------------------------------------------------------------------------------------------------------------

原来的时候JIT是.NET编程的一个特点。(后来,Java好像也有JIT了,只是用得少。but who cares?)

因为Java是先编译为中间代码,后由虚拟机jvm解释执行的。理论上可以一次编译,多处运行,就是会慢一点。

而C是直接编译成机器码运行的。很快,但在不同平台上要多次编译。

而.NET代码是先编译为中间代码,再编译为机器码执行的。这样就是第一次运行慢一点,后面就快了。

-------------------------------------------------------------------------------------------------------------------------------------------------------

总体来说,.NET的特点就是.NET的设计本身。

  • 一个设计的点是,多种语言向IL转化。
  • 另一个设计点是,IL会被CLR进行JIT生成机器码。

不仅跨平台,而且跨语言。

它的前提是在各个不同平台上实现.NET API和CLR。

----------------------------------------------------------------------------------------------------------------------------------------------------------

贴一段.NET的历史。

本身.NET Framework的设计,包括上面语言的设计都是非常良好的。但就是不开源,而且基本上只在Windows上有API和Runtime。

后来Xamarin公司自己基于.NET的设计实现了一套Mono,Mono 是跨平台的实现,它可以运行在 Windows 、 Linux、FreeBSD、Unix、OS X 、 Solaris、Playstation 3、Wii 、 XBox 360等系统上。

大概是因为Java的开源,还有mono的开源所逼的,微软也开源了。

.NET Framework开源。

Xamarin直接被微软买了过来,用VS可以直接新建Xamarin程序了,微软也做了自己的.NET开源跨平台实现------【.NET Core】。

前段时间还听说有人要在浏览器端实现.NET设计,这样就能用C#写前端,统一前后端语言了,目前感觉不是很靠谱的样子。

然后前段时间下载VS的时候我发现VS也是开源的。

github也被微软买了过来,微软还开源了windows计算器。

常见类型系统

指的是.NET中包含5中常见类型:类,结构体,枚举类型,接口,委托。

最基本的类型当然是:值类型,引用类型。

其他常见的东西,像是public,override这些修饰词;但没有通用到常见类型系统的程度。

为什么.NET要提出【常见类型系统Common Type System】呢?

因为.NET要跨语言实现,语言之间需要有一定的共性。

各种语言都要调用同样的【语言无关的组件Language-Independent Components】。

所以各种语言中都要有CTS中的这些东西。

所以常见类型系统是跨语言的关键。

目标框架

我的代码可以把一个【.NET Standard】作为目标框架。

【.NET Standard】是微软文档中的说法,它包括了【.NET APIs】,还包括了【所有可以引用的东西】。要我自己说就是【.NET APIs】嘛。

也就是说【.NET Standard】是.NET的标准设计,而各套【.NET APIs】是具体实现,各套具体实现可能还包含自己特有的内容。

为什么要有目标框架的概念呢?因为各套【.NET APIs】之间存在差异,通过特定的API才能获得特定的功能。

例如,你要把将目标框架设置为【Xamarin.iOS】才能获得IOS10上特有的功能。

以下截图来自微软文档,列出了实现了【.NET Stantard】的一些【APIs】版本。

当然,微软文档认为的目标框架,不只是【APIs】的版本,但那样说这个列表就太长了,不容易把握。

并且,可以通过一些配置文件或者特殊的标记语法,来指定目标框架。

这个目标框架呢,就是跨平台的关键。

托管代码

托管代码托管了什么?托管是指,CLR编译IL代码,并且执行,而非源码本身直接被编译和执行。

编程的本质是操作内存对象,而内存管理/边界安全/类型安全,对程序员是一种负担。托管的意义就在于解放程序员。

能不能调用非托管代码?可以。

C#中可以通过[DllImport()]特性引用C写的函数。

那能不能写非托管代码?可以。

C#中可以可以在unsafe的花括号内写非托管代码,这一小段非托管代码里面,你就自己管理内存了,这段代码不会编译成IL,而会直接编译成二进制,并且可以使用指针。

Visual Studio

编辑器好用,写起来6,也是一个特点吧。

面向对象

字段,属性,方法。

封装,继承,接口。

什么都不缺,并且是真正的完全面向对象的,没有设计上的漏洞,还有自己的设计。

委托和Lambda和事件

委托是方法的类型,委托对象是方法的指针。我可以把方法赋值给委托的实例。

函数不能当参数,但是委托可以。

public delegate string Reverse(string s);

Reverse rev = ReverseString;//把ReverseString方法赋值给了rev对象。接下来rev对象可以直接调用ReverseString方法,也可以当作参数传递。

这样说是非常严谨的;然后看到js里用btn.click(function(){})注册click的响应方法,然后用btn.click()能够直接调用被注册的方法时,总觉得后面缺了一个Invoke()。

-----------------------------------------------------------------------------------------------------------------------------------------------------------

lamda用起来真是666,本来委托类型一行,一个方法至少3行,给委托了实例赋值也得要一行。

而lamda一行就能写出这些意思来。

Func<string,string> rev = (s)=>{return new string(s.Reverse().ToArray());};

Func<string,string>是委托类型。

rev是委托的实例。

等号右边呢是一个匿名方法。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

事件是在委托基础上建立的概念。

一个委托只能将一个方法作为值。

而事件相当于List<Delegate>,并且事件类型重载了-=和+=运算符。

btn.Click+=【某个符合其委托签名的方法】,就相当于listDelegate.Add(【某个符合其委托签名的方法】)。

相应的,-=相当于remove方法。

相比起来,事件有了多次订阅和取消的能力。

泛型T

例如List<int>,当你使用List<int>而不是ArrayList的时候,可以避免取值和存值的拆箱和装箱;并且可以获得VS更加智能的提示。

泛型也是写纯算法的一个前提,可以实现算法重用。

所有具有GetChilds方法或类似方法的对象都可以作为一个T,这就是函数式的看法。

面向对象那一套只能用接口来抽象各种行为,但是不够抽象。

Func<T,List<T>>就能表达T具有GetChilds方法。而且我没有写死方法的名称。

如果用接口写,方法名必须是死的。

这样以后呢,我就可以写出GetAllChilds()方法,像下面这样。

public static List<T> GetAllChilds<T>(T root, Func<T, List<T>> GetChilds)

我可以如下获取所有子路径

我可以如下获取所有的子节点

----------------------------------------------------------------------------------------------------------------------------------------------

可以看出面向对象所讲的重用并不是真正的重用;函数式的重用才是真正的重用。--------算法重用。

面向对象所讲的重用,太依赖于具体的结构。必须是相同名字的才能重用。-----------它是看你叫什么所以你是怎么样的,而函数式的重用关心你做什么你与另一个东西的关系。

函数式的重用实现了数学上追求的一个理念----------不关心事物的定义,只关心事物和事物之间的关系,太美妙了。

面向对象是经验式的,函数式是逻辑推理式的。人同时拥有这两种思维方式,看实际情况哪个顺手就用哪个吧。

-------------------------------------------------------------------------------------------------------------------------------------------------

面向对象中,封装把方法和数据放一起是增加耦合性的。

然后面向对象中两个类之间的过于密切的关系是增加耦合性的。也可以用函数式的两个函数之间的关系来描述。

面向对象中的接口,把部分方法抽离出来,是减少耦合性的。

相比之下函数式的写法没有增加问题本身的复杂程度,就是头疼医头脚疼医脚。

实际的工程中需要怎么做那就是一个经验和权衡的问题了。

LINQ

linq---语言集成查询。

select,where,Aggregate,这些高阶的动词提供了操作数据的简单方法,并且用的这些词跟sql似的,让人很熟悉。

有了它就能愉快的写一些声明式的代码了。

linq最大的好处可能是精简代码,体现代码的意图。

特性Attributes

没什么好说的,给贴个标签,它就有相应的功能了。

声明式的输入校验看着挺合理的,好用就是硬道理。

并行/并发和异步的处理

Task<T>,async,await,Parallel。

【语言级别的异步处理机制】很语义化。

总结

----------------------------------------------------------------------------------------------------------------------------------------------

.NET以.NET Standard作为设计标准,在不同平台上提供了与语言无关的.NET APIs和公共语言运行时。

.NET的常见类型系统【类,结构体,枚举类型,接口,委托】使其能够提供语言无关的组件。

多个版本的目标框架使其实现了跨平台。

----------------------------------------------------------------------------------------------------------------------------------------------

按照.NET的设计,程序员会了一门语言,并且熟悉了一个平台上的框架后就可以编码了,其它的事情都不用管。

并且VS的强大为程序员的编码工作提供了强力支持。

----------------------------------------------------------------------------------------------------------------------------------------------

面向对象的【字段,属性,方法。类,继承,接口】

函数式的【委托,事件,lambda,扩展方法,泛型】

声明式的【LINQ,Attributes】

还有【语言级别的异步编程模型】

.NET不拘泥于某种编程范式,只要是好用的,都会拿来用。

-------------------------------------------------------------------------------------------------------------------------------------------

最后总结下特点

【跨平台】【多范式】。

程序员只需关注核心的设计和编码工作。

其他问题由【APIs,运行时,VS,语言本身的特性】等帮你解决。

这也许就是.NET的特点。 

原文地址:https://www.cnblogs.com/fabao/p/11872259.html