C#4.0 其他特性(经常使用)

来源:互联网 发布:java增加项目角色 编辑:程序博客网 时间:2024/06/03 09:41

可空类型

int c=null;大家都知道这样写是错误的,普通值类型不能赋值位null
int ?d=null; 值类型后边加?表示可空类型,是一种特殊的值类型,这种类型就可以赋值为null;
引用类型不可以这样写,应用类型本身就可以赋值为null;
  1. HasValue
if (e.HasValue)//只有可空类型才能进行判断     {       Console.WriteLine(d.Value);//通过value属性获取值
     }
  1. GetValueOrdefault

Console.WriteLine(x.GetValueOrDefault(100));
        获取可空类型的值如果没有值返回一个默认值 括号中的值就是自己设置的默认值

  1. GetHanCode
Console.WriteLine(x.GetHashCode());//有值就返回值 没有值就返回一个默认值不能指定默认值
  1. 空合并操作符

int z = y ?? 100;// ?? 空合并操作符判断??左边的值如果有值就返回值如果没有
            //就返回??右边的值

string sr=NULL;

  string str = sr ?? "sg";
            //空合并操作符左边不能是普通值类型可以是引用类型也可以是可空类型 同类型只能跟同类型比(可空类型是特殊的值类型)

匿名方法

没有方法名的方法就是匿名方法.

没有方法名怎么调用呢,这时候就用到了委托.将方法复制给委托.这样利用委托变量就可以像普通的方法一样调用.

MyDeledate del2=delegate(int x,int y) {               return x + y;           };

闭包

匿名方法会形成闭包,当一个哈数包含对领一个函数的调用时,或者内部的函数使用的外部函数的变量时,都会形成闭包,闭包可能

会延长外部变量的生命周期

  class Program    {        public delegate void MyDelete();        public static MyDelete del;        public static void Main()        {–––            fun();            del();            del();            //闭包:形成一个没有释放的函数,            //闭包的形成过程:通过del指向fun中的一个匿名方法,del会在程序结束才会释放            //del指向的匿名方法也会在程序结束后释放            //匿名函数不释放,fun函数就不会释放        }        public static void fun()        {            int count = 0;            del=delegate() {                count++;                Console.WriteLine(count);            };        }    }        class Program    {        public delegate void MyDelegate();        public static void Main()        {            MyDelegate del = fun();//将匿名函数作为返回值赋值给委托变量            //这里fun()是方法的调用,要的是fun方法的返回值,而不是为了让del指向fun方法            del();            del();        }        public static MyDelegate fun()        {            int count = 0;            return delegate {                count++;                Console.WriteLine(count);            };        }    }

不仅可以将匿名方法作为返回值赋值给委托,还可以通过参数将匿名方 赋值给委托变量。只要能达到赋值给委托变量的目的就行

迭代器

 public class Vector:IEnumerable    {        private int[] array;        private int size;        public Vector(int n)        {            array = new int[n];            size = 0;        }        //索引器        public int this[int index]        {            get { return array[index];}            set { array[index] = value; }        }        public void add(int x)        {            array[size++] = x;        }        接口中的迭代器的方法              public IEnumerator GetEnumerator()        {            for (int i = 0; i < size; i++)            {                yield return array[i];            }        }    }
自动属性
class program    {        public static void Main()        {            Person p1 = new Person("aa", 23);            Console.WriteLine(p1.Name + p1.Age);        }    }    public class Person    {        public string Name { get; set;}        public int Age { get; set;}        public Person (string name,int age)        {            Name = name;            Age = age;        }    }
在结构体中有自动属性时,构造函数中要显式的调用自身的无参数的构造函数.否则会出现编译错误

当使用之前的那种属性的时候可以不使用this但是必须初始化所有的成员变量

 public Person(string name,int age):this()        {            Name = name;            Age = age;        }

隐式类型

很好用,当类型的名字很复杂或者是你不能确定一个方法会返回什么类型的值的时候就可以用var 根据返回的数据自动判断

类型

var c=199;var 就是隐式类型,声明时不知道变量的类型,需根据值的类类型推断
使用的时候注意一下几点:

1.只能是局部变量,不能是字段。

2.声明时必须初始化

3.变量不能初始化为方法组

 4.不能初始化为null 

5.不能声明为参数

对象初始化器

   使用对象初始化器进行初始化的类中必须有无参的构造函数
 首先调用无参数的构造函数对对象进行初始化,然后调用对象初始化器对字段进行初始化

使用对象初始化器对对象进行初始化,构造函数的小括号可以省略

            Person p = new Person("aa", 32);            Student s1 = new Student() { Id = 2, Name = "aa", Address = "cc" };

集合初始化器

1、对自定义的集合(容器)的初始化   需要使用迭代器和add()方法
class Program    {        public static void Main()        {            Vector v = new Vector(4) { 1, 2, 3, 5 };            foreach (int item in v)            {                Console.WriteLine(item);            }        }    }    public class Vector:IEnumerable//是system.collection下的IEnumerable 不是泛型中的这个接口    {        private int[] array;        private int size;        public Vector(int n)        {            array = new int[n];            size = 0;        }        public void Add(int x)//必须是大写的Add        {            array[size++] = x;        }        public IEnumerator GetEnumerator()        {            for (int i = 0; i < size; i++)            {                yield return array[i];            }        }
2、系统提供的集合则可以直接进行初始化,因为所需的方法系统已经提供

 List<int> li = new List<int>() { 1, 2, 3, 4 };  

匿名类型

匿名类型就是未知的类型,通过隐式类型和对象初始化器创建匿名对象

   var p=new {Name="aa",Age=20};

在创建匿名数组对象时,所有的数据类型要一致

          var pArryay = new[]{                new {Name="aa",Age=20},                new {Name="bb",Age=23},                new {Name="cc",Age=24},                new {Name="dd",Age=25}            };
lambda表达式

lambda 表达式:=>左边是参数,右边是函数体 (参数列表中的参数类型可以省略,必要时再加)

            MyDelegate del2 = (int c, int d) => c + d;            int b = del2(2, 3);            Console.WriteLine(b);
只有一个参数时,用于写参数的小括号可以省略,但是没有参数或多个参数的时候不能省略
            Mydelegate d1= a =>a*a ;//表达式lambda            int x=d1(5);            Console.WriteLine(x);            delgate1 del1 = () =>              {                  Console.WriteLine("hello");//语句lambda              };            del1();
lambda和匿名方法一样,和委托连用也可以形成闭包

Fun泛型委托 是由系统提供的,前边的泛型参数是参数的类型,最后边的泛型参数是返回值类型
    逻辑简单的函数可以用匿名类型和lambda表达式

 Func<int, int> d = a => a * a;            int x = d(5);            Console.WriteLine(x);













原创粉丝点击