• .NET/C# 各版本变化及衍生知识点 C# 1.0/2.0


    还是新开一篇吧,因为不光要记录各版本变化,还想把相关知识点衍生出来扩展一下,一天写不完就多几天,这里面知识点非常多。

    C# 1.0,对应.NET 1.0/1.1,对应VS 2003,新特性:事件、委托。

    C# 2.0,对应.NET 2.0,对应VS 2005,新特性:泛型(Dictionary、List)、匿名、迭代、可空、委托(协变/逆变)、部份类、静态类、属性访问控制

    C# 3.0,对应.NET 3.0/3.5,对应VS 2008,新特性:隐式类型的部变量、对象集合初始化、查询表达式、表达式树、分部类和方法、AJAX、LINQ、Entity Framework、ADO.NET、类型推断(var)、自动属性、匿名类型、扩展方法、Lambda表达式

    C# 4.0,对应.NET 4.0,对应VS 2010,新特性:dynamic、动态绑定、可选(默认)参数、命名参数、泛型的协变和逆变、互操作性

    C# 5.0,对应.NET 4.5,对应VS 2012,新特性:异步编程(async/await)、调用方信息、带参数的泛型构造函数、支持null类型运算、case支持表达式、扩展属性

    C# 6.0,对应.NET 4.6,对应VS 2015,新特性:主构造函数、using静态类、属性表达式、方法表达式、枚举参数、null判断、Constructor type parameter inference、内联out、自动属性增强、字符串嵌入值string.Format变成直接"{变量}"、nameof表达式、异常过滤器、catch和finally 中的 await 、无参数的结构体构造函数

    一、C#1.0

    1、事件、委托

    事件就是一个特殊的委托,委托和事件就类似于字段和属性的关系,事件是对委托做了一个封装
    事件必須用+=或-=(委託可以清空,事件不能清空)
    我们可以将“委托”理解为“方法的抽象”,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。
            public delegate void SaySomething(string name);
            public event SaySomething Come;
            public void SayHello(string name)
            {
                Console.WriteLine("Hello," + name + "!");
            }
            public void SayNiceToMeetYou(string name)
            {
                Console.WriteLine("Nice to meet you," + name + "!");
            }
    
            public void test()
            {
                SaySomething sayhello = SayHello;
                SaySomething saynice = SayNiceToMeetYou;
                Come += sayhello;
                Come += saynice;
                Come("张三");
            }

    大概理解的是:委托相当于“定义”了一个规范(签名相同),由“继承”的具体方法来“实现”,注册事件相当于依次执行委托,也就是执行那些具体的方法。

    因为在项目中没具体用过,所以实在难以理解,只好先这样吧。

    二、C# 2.0

    1、泛型

     一次编码,多次使用、按需实例化、编译时就可以保证类型安全、不用做类型装换、获得一定的性能提升

    泛型类、泛型方法、泛型委托、泛型接口

    格式为<T>最常用的就是List<T>和Dictionary<T,T>,具体类型可以用的时候再定。

    常用来和装箱/拆箱相比较,泛型可以提高性能(不用装拆箱),指定了类型,在编译时容易发现问题。

    private static void DoSomething<T>(T a)
    {
        T b = a;
        Console.WriteLine(b);
    }
    static void Main(string[] args)
    {
        DoSomething("A");
        DoSomething(1);
        Console.ReadKey();
    }

    可以看到,就把T当成是普通的Int或String看待就行,就看具体怎么用

    泛型约束:

    约束
    描述
    where T: struct
    类型参数必须为值类型。
    where T : class
    类型参数必须为类型。
    where T : new()
    类型参数必须有一个公有、无参的构造函数。当于其它约束联合使用时,new()约束必须放在最后。
    where T : <base class name>
    类型参数必须是指定的基类型或是派生自指定的基类型。
    where T : <interface name>
    类型参数必须是指定的接口或是指定接口的实现。可以指定多个接口约束。接口约束也可以是泛型的。

     语法就是 WHERE T : 约束,是用来约定这个泛型只能取什么值的

    interface IMyInterface
    {
    }
    
    class Dictionary<TKey, TVal>
        where TKey : IComparable, IEnumerable
        where TVal : IMyInterface
    {
        public void Add(TKey key, TVal val)
        {
        }
    }

    2、匿名方法

    在使用委托时创建,本来委托要使用一个专门建的方法。但匿名方法可以直接写方法体(js不是天天这么用么。。。),以后有了lamda就更方便了

            delegate void Del(int x);
            Del d = delegate(int k) { /* ... */ };
            Thread t1 = new Thread (delegate() { Console.Write("Hello, "); } );
            ThreadStart ts1 = new ThreadStart(Method1); //可以简写成下面这种
            ThreadStart ts2 = Method1;

    3、迭代器

    迭代器的返回类型必须为 IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>。迭代器是使用在foreach中的集合

    foreach不是for的简写,而是对实现了IEnumerable接口的集合进行遍历

    而如果不想实现IEnumerator又想用foreach的话,可以使用yield return,相当于yield return帮我们实现了IEnumerator

    迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代
      public class Persons : IEnumerable
        {
            public IEnumerator GetEnumerator()
            {
                yield return "1";
                Thread.Sleep(1000);
                yield return "2";
                Thread.Sleep(1000);
                yield return "3";
                Thread.Sleep(1000);
                yield return "4";
                Thread.Sleep(1000);
                yield return "5";
                Thread.Sleep(1000);
                yield return "6";
            }
        }
        class program
        {
            static void Main()
            {
                Persons arrPersons = new Persons();
                foreach(string s in arrPersons){
                    Console.WriteLine(s);
                }
                Console.ReadLine();
            }
        }

    简单的说,迭代器就是foreach,前提条件是IEnumerator,如果没有IEnumerator,就用yield return。

     

    4、可空类型

    int? i = null;
    int j = i ?? 0;

    可空类型经常配合数据库的可空字段使用。

    int本来是不能赋null的,但用了int?,就可以赋null。

    ??是简写的一种运算符,相当于 int j = i==null? 0 : Convert.ToInt16(i);

    注意,可空类型不能直接赋给值类型(因为有可能null),但反过来是可以的。

    5、委托(协变/逆变)

    协变针对委托的返回值,逆变针对参数;  逆变粗糙化,协变精细化

    比较抽象,只了解了个大概

    6、部份类、静态类、属性访问控制

    部份类(partial):一个类长太了,分成两个类(可存放在不同地方),编译时视为同一个类

    静态类(static):不用实例化就能直接访问,并长驻内存。静态类里只能有静态方法,但静态方法不一定要在静态类中。静态类/方法不能访问非静态类/方法,但非静态类/方法(即普通方法)无此限制。

    属性访问控制:get和set前面可以加修饰符来控制访问权限,和类、方法的修饰符一致

  • 相关阅读:
    使用JQuery+HTML写一个简单的后台登录页面,加上对登录名和密码的前端校验。
    Shiro入门3
    Shiro入门2
    Shiro入门1
    Spring+SpringMVC+Mybatis整合 pom示例
    IO(1)----File类
    集合(3)—— Map
    集合(3)—— Set
    集合(2)——List集合
    集合(1)
  • 原文地址:https://www.cnblogs.com/liuyouying/p/5071271.html
Copyright © 2020-2023  润新知