.Net各版本新特性

序言

C# 1.0 (2002)

public interface IDateProvider
{
    DateTime GetDate();
}

隐式接口实现

public class DefaultDateProvider : IDateProvider
{
    public DateTime GetDate()
    {
        return DateTime.Now;
    }
}

显式接口实现

显式接口实现的一个很好的方面是它强制消费者依赖于接口。显式实现接口的实例对象必须使用接口本身,而没有其他可用的接口成员!

public class MinDateProvider : IDateProvider
{
    DateTime IDateProvider.GetDate()
    {
        return DateTime.MinValue;
    }
}

 通过直接使用接口,不会将代码耦合到底层实现。

 IDateProvider provider = new MinDateProvider();

C# 2.0 (2005)

泛型(Generics)

为什么要有泛型?

我们在写一些方法时可能会方法名相同,参数类型不同的方法,这种叫做重载。如果只是因为参数类型不同里面做的业务逻辑都是相同的,那可能就是复制粘贴方法,改变参数类型,例如一些排序算法,int、float、double等类型的排序,参数数组存的数据类型不一样,还有像根据索引找到List集合中的对象。可能这个对象是

Person、Dog等对象,这样方法改变的只是参数类型,那就是能不能写一个方法,传递不同的参数类型呢?于是乎有了泛型。

什么是泛型?

泛型通过参数化类型来实现在同一份代码上操作多种数据类型。例如使用泛型的类型参数T,定义一个类Stack<T>,可以用Stack<int>、Stack<string>或Stack<Person>实例化它,从而使类Stack可以处理int、string、Person类型数据。这样可以避免运行时类型转换或封箱操作的代价和风险,类似C++的模板。泛型提醒的是将

具体的东西模糊化,这与后面的反射正好相反。

 有几种编写泛型类型参数约束的方法,请考虑以下语法:

public class DataBag where T : struct { /* T 值类型 */ }
public class DataBag where T : class { /* T 类、接口、委托、数组 */ }
public class DataBag where T : new() { /* T 有无参构造函数 */ }
public class DataBag where T : IPerson { /* T 继承 IPerson */ }
public class DataBag where T : BaseClass { /* T 派生自 BaseClass */ }
public class DataBag where T : U { /* T 继承 U, U 也是一个泛型参数 */ }

多个约束是允许的,用逗号分隔。类型参数约束立即生效,即编译错误阻止程序员犯错。

C# 3.0 (2007)

匿名类型

 var person1 = new { Name = "learning hard", Age = 25 };

自动实现的属性

/// <summary>
///  姓名
/// </summary>
public string Name { get; set; }

表达树

 

扩展方法

public static class ExtensionMethod
    {
        public static void ShowItems<T>(this IEnumerable<T> colletion)
        {
            foreach (var item in colletion)
            {
                if (item is string)
                {
                    Console.WriteLine(item);
                }

                else
                {
                    Console.WriteLine(item.ToString());
                }
            }
        }
    }

调用扩展方法

  "123123123123".ShowItems();//字符串
   new[] { 1, 2, 3, 4, }.ShowItems();//int数组
   new List<int> { 1, 2, 3, 4 }.ShowItems();//List容器

Lambda表达

static List<int> GetSquaresOfPositiveByLambda(List<string> strList)
{
    return strList
        .Select(s => Int32.Parse(s)) // 转成整数
        .Where(i => i % 2 == 0) // 找出所有偶数
        .Select(i => i * i) // 算出每个数的平方
        .OrderBy(i => i) // 按照元素自身排序
        .ToList(); // 构造一个List
}

查询表达式

 

C# 4.0 (2010)

动态绑定

 

嵌入式互操作类型

 

泛型中的协变和逆变

 

命名/可选参数

可选参数允许为方法的一些参数提供默认值,并允许使用者重载类型,因此,即使只有一个方法,也能处理所有变体

public void test(string a, string b, int c, bool d=true,bool e=false)
{

}

调用:

public void invoke()
{
      test("li", "dd",7);
      test("li", "dd", 7,false);
      test("li", "dd", 7, true,false);
}

C# 5.0 (2012)

异步/等待

Console.WriteLine("主线程开始");
Task<string> task = Task<string>.Run(() => { Thread.Sleep(1000); return Thread.CurrentThread.ManagedThreadId.ToString(); });
Console.WriteLine(task.Result);
Console.WriteLine("主线程结束");

调用方信息

 

C# 6.0 (2015)

字典初始化

          class StudentName 
            { 
                public string FirstName { get; set; } 
                public string LastName { get; set; } 
                public int ID { get; set; } 
            } 
 
            class CollInit 
            { 
                Dictionary<int, StudentName> students = new Dictionary<int, StudentName>() 
                { 
                    { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}}, 
                    { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}}, 
                    { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}} 
                }; 
            }

异常过滤器

 try
{

}
catch (Exception)
{
                
}
finally
{

}

表达式体成员

 

nameof 操作符

Console.WriteLine(nameof(Int32));

空合并运算符

??被称为【可空合并】运算符,是一个二目运算符,操作参数两枚,其完成的功能为对左参数判断之后进行赋值。

       返回结果:如果左操作数不为空,则返回左操作数本身;如果左操作书为空,则返回右操作数。

       格式:object1 ?? object2 

int? x = null;
int y = x ?? -1;
Console.WriteLine(string.Format("x={0},y={1}", x, y));

属性初始化

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Address { get; set; }
}
Person person = new Person { Name = "Slark", Age = 100, Address = "Xi'an" };
List<int> intList = new List<int> { 1, 2, 3 };
List<Person> personList = new List<Person>
{
    new Person { Name = "Slark1", Age = 101, Address = "Xi'an1" },
    new Person { Name = "Slark2", Age = 102, Address = "Xi'an2" },
    new Person { Name = "Slark3", Age = 103, Address = "Xi'an3" }
};

静态引用

 

字符串插值

 编程中经常用到字符串的拼接。 

class Plane
{
      public string Category { get; set; }
      public string Name { get; set; }
      public int State { get; set; }
}

C#6.0之前的方法:

var p = new Plane() { Category = "A", Name = "B", State = 0 };
var sb=new StringBuilder();
sb.Append(string.Format("Category={0},Name={1},State={2}",plan.Category,plane.Name,plane.State);

C#6.0之后的方法:

var p = new Plane() { Category = "A", Name = "B", State = 0 };
var sb=new StringBuilder();
sb.Append($"Category={p.Category},Name={p.Name},State={p.State}");

C# 7.0 (2017)

表达式体成员

 

局部方法

 

Out 变量

 

模式匹配

static dynamic Add(object a)
        {
            dynamic data;
            switch (a)
            {
                case int b:
                    data=b++;
                    break;
                case string c:
                    data= c + "aaa";
                    break;
                default:
                    data = null;
                    break;
            }
            return data;
        }

匹配模式的Case When筛选

switch (a)
            {
                case int b when b < 0:
                    data = b + 100;
                    break;
                case int b:
                    data=b++;
                    break;
                case string c:
                    data= c + "aaa";
                    break;
                default:
                    data = null;
                    break;
            }

局部引用和引用返回

public static void DoSomeing()
        {
            //调用Dosmeing2
            int data = Dosmeing2(100, 200);
            Console.WriteLine(data);
            //定义局部函数,Dosmeing2.
            int Dosmeing2(int a, int b)
            {
               return a + b;
            }
        }

元组

static void Main(string[] args)
 {
            var data = GetFullName();
            Console.WriteLine(data.Item1);
            Console.WriteLine(data.Item2);
            Console.WriteLine(data.Item3);
            Console.ReadLine();
}
static Tuple<string, string, string> GetFullName() 
{
           return  new Tuple<string, string, string>("a", "b", "c");
}

 解构元组

有的时候我们不想用var匿名来获取,那么如何获取abc呢?我们可以如下:

static void Main(string[] args)
        {
           //定义解构元组
            (string a, string b, string c) = GetFullName();

            Console.WriteLine(a);
            Console.WriteLine(b);
            Console.WriteLine(c);
            Console.ReadLine();

        }

        private static (string a,string b,string c) GetFullName()
        {
            return ("a","b","c");
        }

 

 

 

https://www.cnblogs.com/microsoft-zyl/p/9093748.html

转载于:https://www.cnblogs.com/cnki/p/8303444.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值