专栏首页草根专栏C# 7.0简而言之 -- 01. C#和.NET Framework简介
原创

C# 7.0简而言之 -- 01. C#和.NET Framework简介

该系列文章大量参考了 C# 7.0 in a nutshell 一书:

面向对象

C# 语言对面向对象范式进行了丰富的实现, 当然包括封装, 继承和多态.

1. 统一的类型系统

C#里面所有的类型都有一个共享的基类, 这也意味之C#里面所有的类型都具备一些相同的基本功能, 例如任何类型都可以通过调用ToString()方法来转化成字符串.

2. 类和接口

传统的面向对象范式里面, 只有一种类型就是class. 而在C#里面还有几种其他的类型, 这里就包含接口(interface).

在C#里面, 在需要多继承的情况下就应该使用接口, 因为C#不支持多继承.

3. 属性(Property), 方法和事件(event)

在纯面向对象范式里面, 所有的函数(function)都是方法(method)(例如Smalltalk语言). 在C#里, 方法只是函数成员(function members)的一种, 其他的成员还包括属性(property)以及事件(event), 此外还有其它的类型.

属性(Property)是一种可以封装对象一部分的状态的函数成员.

事件(Event)这种函数成员会在对象状态变化的时候进行响应.

可以说C#主要是一种面向对象的语言, 但是它也借鉴了函数式编程范式的特点, 尤其是:

1. 函数(functions)可以作为值来处理

通过委托(delegate), C#允许函数可以像值一样在函数间进行传递.

2. C#支持模式简洁

函数式编程的核心思想就是尽量不要使用值会变化的变量, 并拥护陈述模式. C#通过它额特性对该模式进行支持. 例如: lambda表达式(它是一种可即时编写并能”俘虏”变量的匿名函数). C#还有能力通过查询表达式来执行列举动作或响应式编程. 同时C#可以很简单地通过定义只读字段(field)和属性(property)来实现不可变(immutable, 或叫只读)类型.

类型安全

C#主要还是一种类型安全的语言, 也就是说类型的实例之可以通过预定的协议进行交互, 这样就可以保证类型内部的一致性.

C#也支持静态类型, 这意味着C#在编译时就保证了类型安全.

C#虽然可以通过dynamic关键字来实现动态类型, 但它主要还是个静态类型语言.

C#同时也被称为强类型语言, 因为它的类型规则十分的严格.

内存管理

C#依赖于运行时来实现自动化的内存管理工作. CLR(Common Language Runtime)通用语言运行时, 它有个垃圾收集器(GC), GC会作为你程序的一部分来执行, 它会处理掉不再引用的对象并回收内存. 这也消除了像某些语言中使用指针来解除内存分配可能遇到的问题, 例如C++.

另外一点需要注意的就是C#没有消灭指针, 只不过大多数情况下根本不需要使用指针. 但是针对性能要求比较高或需要互操作的时候可以使用指针和明确的内存分配, 但这部分代码必须写在标明了unsafe的块里.

平台支持

Windows, Linux, macOS, iOS, Android.

C# 和 CLR

C# 依赖于运行时来提供很多功能, 例如自动内存管理和异常处理等. .NET Framework的核心就是一个运行时: CLR(通用语言运行时).

C#是一种托管语言, 它可以被编译成托管代码, 托管代码是使用的是IL语言(Intermediate Language, 中间语言). CLR会把IL转化成实际运行机器的本地代码, 例如X86或X64的机器, 通常就是在运行之前执行. 这可以叫做即时编译(JIT, Just-in-time). 也可以使用预编译(AOT, Ahead-of-time), 在组件(assembly)较多或资源紧缺的设备上使用AOT可以提升程序启动速度.

托管代码的容器叫做组件(assembly)或者便携式可执行文件. assembly可以是一个exe或者dll, 它里面不仅包含IL还包含类型信息(metadata, 元数据).

可以使用微软的ildasm工具来查看IL assembly.

CLR和.NET Framework

.NET Framework由CLR和其它大量的库组成. 这些库由核心库(本系列文章主要讲的就是这个)和应用库, 而应用库也是依赖于核心库的. 请看下图:

圆圈里面的是要写的, 外边的不会介绍.

其它框架

  • UWP, 支持win10设备, 除了PC之外还包括XBox, Win10手机, Surface Hub, Hololens等等.
  • .NET Core, 跨平台的开源框架, 支持Windows, macOS, Linux. 与传统的.NET Framework不同, .NET Core可以进行自包含的部署.
  • Xamarin, 使用它可以为iOS, Android以及Windows移动设备编写原生的应用, Xamarin这个公司再2016年被微软收购.undefined书里面没提到Unity

下面是这几个主流框架对平台支持情况的列表:

FoxitReader_2018-04-25_16-47-23.png

遗留框架和小众框架

遗留的框架主要有:

  • WinRT
  • Windows Phone 7/8
  • XNA
  • Silverlight
  • .NET Core 1.x

值得一提的小众框架有:

  • .NET Micro Framework, 它主要应用于资源紧缺的嵌入式设备.
  • Mono, 是传统.NET Framework的开源实现, 跨平台, 但不是所有功能都实现了.undefined还有一个值得一提的就是可以在SQL Server里面运行托管代码, 使用SQL Server CLR, 你可以使用C#编写自定义函数, 存储过程和聚合.

C#简史

C# 7.0 有什么新东西(现在C# 7.1已经有了)

数字分隔符

            // 数值
            int million = 1_000_000;
            float millionWithDecimal = 1_000_000.000_002f;

            // 使用二进制
            var b = 0b1010_1011_1100_1101_1110_1111;

out变量

可以在方法参数的行内直接声明out变量:

bool successful = int.TryParse("123", out int result);

此外, 当你调用一个含有多个out参数的方法的时候, 你可以忽略那些你不感兴趣的out 参数, 使用下划线"_"即可:

SomeMethod(out _, out _, out _, out int x, out _, out _, out _);

模式变量

你可以使用is操作符来随时引入变量. 这就叫做模式变量:

        void Foo(object x)
        {
            if (x is string s)
            {
                Console.WriteLine(s.Length);
            }
        }

switch语句也支持模式变量:

            switch(x) {
                case int i:
                    Console.WriteLine("int!");
                    break;
                case string s:
                    Console.WriteLine(s.Length);
                    break;
                case bool b when b == true:
                    Console.WriteLine("True");
                    break;
                case null:
                    Console.WriteLine("Nothing");
                    break;
            }

本地方法

本地方法就是在某个方法里面声明的方法:

        void WriteCubes()
        {
            Console.WriteLine(Cube(3));
            Console.WriteLine(Cube(4));
            Console.WriteLine(Cube(5));
           int Cube(int value) => value * value * value;
        }

更多的expression-body成员

C# 6里面为方法, 只读属性(property), 操作符和索引器引进了expression-bodied "宽箭头"的语法. C# 7里面把该语法扩展到了构造函数, 读写属性, 和总结器(finalizer):

    public class Person
    {
        string name;

        public Person(string name) => Name = name;

        public string Name
        {
            get => name;
            set => name = value ?? "";
        }
        
        ~Person() => Console.WriteLine("finalize");
    }

析构函数 Deconstructors

C# 7 里面引入了析构函数模式. 构造函数的作用通常是把一组(参数)值赋給字段, 而析构函数则是做了相反的事, 把字段赋給一组变量:

        public void Deconstruct(out string firstName, out string lastName)
        {
            int spacePos = name.IndexOf(' ');
            firstName = name.Substring(0, spacePos);
            lastName = name.Substring(spacePos + 1);
        }
        ... ...
        ... ...
            var joe = new Person("Joe Bloggs");
            var (first, last) = joe;
            Console.WriteLine(first); // Joe
            Console.WriteLine(last); // Bloggs

元组 Tuple

C# 7 里面支持显式元组:

            var bob = ("Bob", 23);
            System.Console.WriteLine(bob.Item1); // Bob
            System.Console.WriteLine(bob.Item2); // 23

            var tuple = (Name: "Bob", Age: 23);
            System.Console.WriteLine(tuple.Name); // Bob
            System.Console.WriteLine(tuple.Age); // 23

使用元组, 函数可以返回多个值, 也就无需使用out参数了:

            var pos = GetFilePositon();
            System.Console.WriteLine(pos.row); // 3
            System.Console.WriteLine(pos.column); // 10

元组支持解析模式:

            (int row, int column) = GetFilePositon();
            System.Console.WriteLine(row); // 3
            System.Console.WriteLine(column); // 10

抛异常

在C# 7以前, throw 肯定是一个语句. 而现在它可以作为expression-bodied 函数的表达式了:

public string Foo() => throw new NotImplementedException();

throw表达式也可以出现在三元状态表达式里:

        string Capitalize(string value) => 
            value == null ? throw new ArgumentException("value") :
            value == "" ? "" :
            char.ToUpper(value[0]) + value.Substring(1);

其它的改进

C# 7 里面还有很多改进没有写, 这些会在以后的文章中提到.

C# 6 新特性

null条件("Elvis")运算符

它可以在访问类成员之前避免手动的去检查该类对象是否为null.

            StringBuilder sb = null;
            string result = sb?.ToString();

Expression-bodied 函数

它允许使用一行表达式来完成方法, 属性, 操作符, 索引器:

        public int TimesTwo(int x) => x * 2;
        public string SomeProperty => "Property Value";

属性初始化器

可以为自动属性赋初始值了:

public DateTime TimeCreated { get; set; } = DateTime.Now;
public DateTime TimeCreated { get; } = DateTime.Now; // 只读属性也可以

索引初始化器

            var dict = new Dictionary<int, string>()
            {
                [3] = "three",
                [10] = "ten"
            };

字符串插值

string s = $"It is {DateTime.Now.DayOfWeek} today";

异常过滤器

string html;
try
{
    html = new WebClient().DownloadString("http://test");
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
{
    ...
}

引入静态成员

使用 using static 指令可以直接引入一个类型的所有静态成员, 然后使用的时候就可以不写类名了:

using static System.Console;
...
 WriteLine("Hello World");

nameof 操作符

nameof 操作符可以返回变量, 类型, 和其它符号的名字(字符串), 这样就可以避免在重命名符号的时候造成代码错误.

            int capacity = 123;
            string x = nameof(capacity); // "capacity"
            string y = nameof(Uri.Host); // "Host"

还有一点值得一提

现在可以在catch 和 finally块里使用await了.

C# 5 新特性

主要是 async 和 await, 这个会在以后的文章具体介绍.

C# 4, 3, 2的新特性

就不介绍了...

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 优秀程序员必备的15大技能

    1.分享 尽可能地使用开源,并且如果有能力的话也可以把自己的成果分享给大家。整个社会的智慧结晶肯定比一些大公司自管自闭门造车要好。 2.公平的心态 不要以为你的...

    用户1667431
  • Linux下使用Nginx端口转发出现502错误的一种解决办法

    今天圈里的一个朋友在配置完nfinx80端口转发到5000后,发现一个问题 问题描述: 正确配置了Nginx80端口转5000端口,在CentOS上把.Net ...

    码农阿宇
  • 为什么我们不要 .NET 程序员

    也许你已经知道了,我们正在招聘最优秀的程序员。不错,每个人都这样说。但是我们的程序员能打败你们的——任何时候。比如,米奇虽然只有5英尺高,但他是一个有相当实力的...

    用户1667431
  • TreeNode.trage的使用

    对于trage的使用 msdn是这样解释的 TreeNode.Target 属性 .NET Framework 2.0 其他版本 注意:此属性在 .NET ...

    码农阿宇
  • 用C# (.NET Core) 实现抽象工厂设计模式

    本文的概念性内容来自深入浅出设计模式一书. 上一篇文章讲了简单工厂和工厂方法设计模式 http://www.cnblogs.com/cgzl/p/8760250...

    solenovex
  • 用C#(.NET Core) 实现简单工厂和工厂方法设计模式

    本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. ? 这就是一...

    solenovex
  • 你真的需要了解多种编程语言吗?

      英文原文:Do You Need To Know More Than One Language  我在谋杀自己的职业生涯。没错,很多人都这样说我。   我的...

    春哥大魔王
  • 写给.net程序员转java的ppt

    ?----

    春哥大魔王
  • .Net做大型互联网项目性能差?看看StackOverflow的架构是怎么样的?

    小编: 在整个web开发世界里,java,.net,PHP是三足鼎立的状况,但是相对于java和php都有优秀的大型互联网架构解决方案,.net的响应架...

    春哥大魔王
  • 互联网技术人才招聘分析报告——什么语言的程序员最受CEO青睐?

    互联网技术人才招聘分析报告——什么语言的程序员最受CEO青睐? ? 对每个创业CEO而言,都会花大量的时间寻找支撑业务发展的优秀人才,那到底什么语言的程序员“最...

    用户1667431

扫码关注云+社区

领取腾讯云代金券