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 关键字用于基类,也不能作为类型参数,不能作为接口实现的一部分