浅学C#(29)——C#的改进:自动属性、对象初始化器、类型推理、Lambda、yield等

版权声明:转载请注明出处 https://blog.csdn.net/le_17_4_6/article/details/86673450

C#语言的改进

自动属性

利用自动属性,可以用简化的语法声明属性,C#编译器会自动添加未键入的内容
编译器会声明一个用于存储属性的私有字段,并在属性的get和set块中使用该字段

public  int  MyProp
{
     get;
     set;
 }

使用自动属性时,只能通过属性访问数据,不能通过底层的私有字段访问,因为我们不知道底层私有字段的名称
自动属性必须包含get和set访问块,无法使用这种方式定义只读或只写属性

对象初始化器

实例化对象时,要为每个需初始化的,可公开访问的属性或字段使用名-值对,来提供其值

<className>  <variableName>=new <className>
{
     <propertyOrField1>=<value1>,
     <propertyOrField2>=<value2>,
     ……
     <propertyOrFieldN>=<valueN>
 }
public  class  Curry
{
    public  String  MainIngredient   {  get;  set;  }
    public  String  Style { get;  set; }
    public  String  Spiciness  { get;  set; }
}

Curry  tastyCurry=new  Curry( );
tastyCurry.MainIngredient=“panir  tikka”;
tastyCurry.Style=“jalfrezi”;
tastyCurry.Spiciness=18;

如果类定义中未包含构造函数,这段代码就使用C#编译器提供的默认无参数构造函数
为了简化这个初始化过程,可以提供一个合适的非默认构造函数

public  class  Curry
{
    public  Curry(string  mainIngredient,  string  style, int  spiciness)
   {
         MainIngredient=mainIngredient;
         Style=style;
         Spiciness=spiciness;
   }
  ……
}
Student   sdt=new  Student
{
     Name=“Mary”,
     Age=30,
     Sex=“女”
 };

类型推理

var =;
变量隐式地类型化为value的类型
如果编译器不能确定var声明的变量类型,代码就不会编译。因此,在用var声明变量时,必须同时初始化该变量,因为如果没有初始值,编译器就不能确定变量的类型

var  myVar=5;
var  myArray=new[] {3,4,5};

初始化器使用的数组元素必须是以下情形的一种
相同的类型
相同的引用类型或空
所有元素的类型都可以隐式地转换为一个类型
var myArray=new[] {3,”not an int”,5};不会编译

匿名类型
var stu = new 
{
    Name = "Mary",
    Age = 32,
    Sex = "女"
};

匿名类型在内部有一个标识符,但不能在代码中使用
如果要在数据存储对象中修改属性的值,就不能使用匿名类型

动态类型

动态变量是类型不固定的变量

仅在编译期间存在,在运行期间会被System.Object代替
dynamic myDynamicVar;

高级方法参数

有些方法有大量的参数,许多参数并不是每次调用都需要的
可选参数

 public List<String> GetWords(String sentence, bool capitalizeWords)
{
            ……
}
 public List<String> GetWords(String sentence)
{
      return GetWords(sentence,false);
}
 p.GetWords("hello,students", false);

Lambda表达式与匿名方法

匿名方法
匿名方法纯粹是为了委托目的而创建的

delegate (parameters)
{
     ……
 };

Lambda表达式的组成
放在括号中的参数列表
=>运算符
C#语句或表达式
编译器会提取这个Lambda表达式,创建一个匿名方法,Lambda表达式和匿名方法会被编译为相同或相似的CIL代码
Lambda表达式的参数
隐式参数(a,b)=>a+b

显式参数(int a,int b)=>a+b

不能在同一个Lambda表达式中同时使用显式的
和隐式地参数类型
如果只有一个参数,可省略括号

Lambda表达式的语句体

PerformOperations((a,b)=>a+b); 可改写为

PerformOperations(delegate(a,b)=>
{
     return a+b;
});

PerformOperations((a,b)=>
{
     return a+b;
}); 
yield

yield
C# 2.0添加了yield语句,以便于创建枚举器
yield return返回集合的一个元素,并移动到下一个元素上
yield break可停止迭代
yield语句会生成一个迭代器,而不仅仅生成一个包含的项的列表。这个枚举器通过foreach语句调用。从foreach中依次访问每一项时,就会访问枚举器。这样可以大大减少迭代大量的数据,而无需一次把所有的数据都读入内存
包含yield语句的方法或属性也称为迭代块,迭代块必须声明为返回IEnumerator或IEnumerable接口,或者这些接口的泛型版本。这个块可以包含多条yield return语句或yield break语句,但不能包含return语句
使用迭代块,编译器会生成一个yield类型,其中包含一个状态机
yield类型实现IEnumerator和IDisposable接口的属性和方法

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace{
    class Program
    {
        static void Main(string[] args)
        {
            HelloCollection helloCollection = new HelloCollection();
            foreach (string s in helloCollection)
            {
                Console.WriteLine(s);
            }

            Console.ReadKey();
        }
    }

	//以下是使用yield和不使用yield
    //public class HelloCollection : IEnumerable
    //{
    //    public IEnumerator GetEnumerator()
    //    {
    //        yield return "Hello";
    //        yield return "World";
    //    }
    //}

    public class HelloCollection : IEnumerable
    {
        public IEnumerator GetEnumerator()
        {
            Enumerator enumerator = new Enumerator(0);
            return enumerator;
        }

        public class Enumerator : IEnumerator, IDisposable
        {
            private int state;
            private object current;

            public Enumerator(int state)
            {
                this.state = state;
            }

            public bool MoveNext()
            {
                switch (state)
                {
                    case 0:
                        current = "Hello";
                        state = 1;
                        return true;
                    case 1:
                        current = "World";
                        state = 2;
                        return true;
                    case 2:
                        break;
                }
                return false;
            }

            public void Reset()
            {
                throw new NotSupportedException();
            }

            public object Current
            {
                get { return current; }
            }
            public void Dispose()
            {
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/le_17_4_6/article/details/86673450