C#进阶学习第十四天

1.扩展方法

1.用来扩展已经定义类型的方法成员。为现有的类型添加方法
2.在静态类中扩展方法,至少有一个参数,这个参数前加this, this后边是要扩展的类对象
3.不同的封闭泛型,扩展的方法也不一样

    //1.扩展自定义类的方法
    public class  person
	{   public string Name {get;set;}  public int Age {get;set;}
	    public person(string name,int age){  Name = name; Age = age;}
	}
	public static class   externperson
	{   public static void print(this person p)
	    { Console.WriteLine ("姓名:{0}   年龄:{1}" ,p.Name,p.Age);}
	}
    int main()
    {person p = new person ("落海", 22); p.print ();}
    
    //2.扩展系统提供的类的方法
    public static class externList
	{   public static  int tosum(this List<int> li)
		{int c = 0;foreach (int item in li){c += item;}return c;}
		public static int tosum(this List<int > li , int n)
		{ int c = 0; for (int i = 0; i < n; i++){c += li [i];}return c;}
	    }
    int main()
    {   List<int > t = new List<int> ();
	    for (int i = 1; i <=100 ; i++) { t.Add (i);}
	    Console.WriteLine (t.tosum());	
		Console.WriteLine (t.tosum(50));
    }

注:
1.必须在一个非嵌套,非泛型的静态类中定义
2.至少有一个参数
3.第一个参数必须加上this 关键字
4.第一个参数不能使用任何其他的修饰符
5.第一个参数不能是指针类型
静态类不能创建对象(abstract),不可以被继承(sealed),
不能声明非静态成员(实例成员) 只能声明静态成员

2.扩展方法查找规则

对象在调用某方法时,首先在该类中查找方法。无则去查找扩展方法。
在查找扩展方法时,首先在当前命名空间查找,再去引入其他的命名空间查找。
注:
扩展方法可以重载,调用时根据参数选择用哪个扩展方法。
如果参数也一样,不同的命名空间可以一样,同一个命名空间下不可以
空引用,调用实例方法将会抛出异常,但可以调用扩展方法。
字类可以调用父类的扩展方法。扩展方法可以继承到子类中。

    public static void fun(this object c){ console.writeline(“sss”); }
    //所有子类都可以调用此扩展方法。

3.可选实参

声明形参时,给其添加默认值,当调用函数时,就可以不传参,用默认值计算
如果实参有值,传参数用实参的值,实参传一个参数将代替形参默认的第一个参数
字类中不显示调用父类构造函数时,会自动调用父类无参构造函数
或构造函数的参数带默认函数
注:
可选实参必须放在必选实参的后面
可选实参的默认值必须为常量 : 数字,常量字符串,null,const成员,枚举成员
数组不能为可选实参 //public static void fun(new a[] t =null) //报错
用ref 和 out关键字标识的参数不能为可选实参 //public static void fun(ref int a) 报错

    public static void addd(int a=3,int b=5){Console.WriteLine (a+b);}
    public static void addd(int b, int a=2){ … }   //必选,可选
    int main()
    {   addd ();  addd (5);  addd (6, 6);  }

4.命名实参

int main(){ addd(b:2); } //b是addd()方法中的形参名字

5.泛型的可变性

泛型参数的转换,从子类赋值给父类,不行,加上out关键字,使泛型参数支持协变性

    public interface  myinterface<out T>{}
    myinterface<student> t = null; myinterface<person> tb = null;  tb =t;

6.泛型的逆变性

赋值过程中,泛型参数从父类到子类,叫做逆变性,用关键字in

    public interface  myinterface<in T>{}
    myinterface<student> t = null; myinterface<person> tb = null;  t =tb; 

泛型参数作为返回值时,只能发生协变,从子类到父类
泛型参数作为参数时, 只能逆变, 从父类 到子类
泛型的协变逆变,指的是泛型参数(泛型接口 或 泛型委托中的泛型参数) 的协变逆变
注:
1.只有接口和委托才支持泛型参数的协变和逆变,类或泛型方法的类型参数都不支持
2.协变和逆变只适用于引用类型。值类型不支持
3.必须显示的用in out标记类型参数
4.委托的可变性不要再多播委托中使用

7.动态型(很少用)

1.只有在程序执行过程中才能确定类型
2.使用ExpandObject 来实现自己的动态行为,添加新的方法和属性
dynamic e = new ExpandoObject ();
e.Name = “luo hai”; e.Age = 24;
e.Addmethod = (Func <int,int>)(x => x + 1); //指明委托类型
Console.WriteLine (e.Name +e.Age);

1.不能用来调用扩展方法
2.委托与动态类型之间不能进行隐式转换 dynamin s = x=>x+1 //报错!
3.不能调用构造函数和静态方法
4.不能讲dynamin 关键字用于基类,也不能作为类型参数,不能作为接口实现的一部分

猜你喜欢

转载自blog.csdn.net/JingDuiTell/article/details/88785484