c# 扩展方法奇思妙用
http://www.cnblogs.com/ldp615/archive/2009/08/07/1541404.html
第一节 、字段与属性的初始化方式汇总
1、对象与集合初始化器:可初始化部分的字段。
A obj3 = new A{IntValue = 100}; //对象初始化器
List<A> objs = new List<A>{ //集合初始化器
new A{IntValue =100},
new A{IntValue =200}
};
【注意】使用初始化器时,类A必须要定义无参数的构造函数,而且属性IntValue是Public,否则编译不能通过。
2、 自动实现的属性
A、 class A
{ public int IntValue {get;set;} }
B、 当定义只读的属性时
class MyClass
{ public ReadOnlyValue {get;private set;}
3、 声明式的属性初始化方式:
<asp:Button ID=”Button1” runat=”server”Text=”Click” onclick=”Button_Click” />
4、 基于反射初始化对象字段与属性
public class MyHost{
[Import(typeof(IplugIn))]
Public IplugIn plugin = null;
//……
}
5、 使用Tuple 对象作为方法的形参或返回值
A、 Tuple类代表一个有序的N元组,比如3元组(100,200,300)
B、 使用new 关键字直接创建一个Tuple对象,它支持1~7个泛型参数的泛型Tuple.
static Tuple<int,int> Divide(int x,int y)
{ return new Tuple<int,int>(x / y,x % y); }
调用: Tuple<int,int> result = Divide(10,3);
Console.WriteLine(“{0} {1}”,result.Item1,result.Item2);
C、 Tuple实现了IStructuralEquatable、IstructuralComparable、Icomparable接口
D、 Tuple的元素可指定为任意类型,这使得它有很强的表达力的数据类型。
第三节 命名参数与可选参数
1、 意义:A、为方便快捷地调用本地COM组件中的方法。B、可以减少重载方法的数量。
2、 命名参数的例子: static void SomeMethod(int x1,int x2,int y1,int y2)
调用时:SomeMethod(x1:100,y1:300,x2:200,y2:400); //命名方式,次序无关紧要
3、可选参数:是指给方法的特定参数指定默认值,在调用方法时,可以省略掉这些参数。
static void Test(int required,string optionalString=”Default Value”) {……}
Test(100); //optionalString参数拥有默认值”Default Value”
Test(100,”New Value”); //optionalString参数的值为”New Value”
4、拥有可选参数的重载方法的调用原则:
A、根据实参类型,参数最接近的方法被调用。
B、如果根据上条规则有两个或多个重载方法都可以被调用,选择参数个数最小的。
第一节 方法的重载、隐藏与重写辨析
1、 方法的重载的判定条件:
A、方法名相同。
B、方法参数列表不同。
B.1 方法的参数数目不同。
B.2 方法拥有相同数目的参数,但参数的类型不一样。
B.3 方法拥有相同数目的参数和参数类型,但参数类型出现的先后顺序不一样。
方法返回值类型不是方法重载的判定条件。
2、 方法的隐藏:
A、 当子类与父类有完全一样的方法时,称子类隐藏了父类的同名方法。
B、 当分别位于子类与父类的两个方法完全一样时,调用哪个方法由对象变量的编译时类型决定。
C、 当定义方法隐藏时,需在子类中定义的同名方法前加 new 关键字。
class Parent {
public void HideF() {Console.W riteLine(“Parent.HideF()”);
}
class Child:Parent{
public new void HideF() {Console.W riteLine(“Child.F()”);
}
Child c = new Child(); c.HideF(); //输出:Child.HideF()
Parent p = new Parent(); p.HideF(); //输出:Parent.HideF()
Parent x = new Child(); x.HideF(); //输出:Parent.HideF()
3、方法重写与虚方法调用:
A、在父类同名方法前加关键字Virtual,表明是一个虚方法。在子类同名方法前加关键字override,表明对父类同名方法进行了重写。
B、调用同名方法时,由变量所引用对象的真实类型决定。
C、正是C#的“虚方法调用”特性,使我们可以只用同样的一个语句,在运行时根据对象类型而执行不同的操作,让代码具有“运行时功能可变”的特性。
Class Parent {
Public virtual void f() {Console.WriteLine(“Parent.f()”);}
}
Class Child: Parent{
Public override void f() { Console.WriteLine(“Child.f()”);}
Parent b = new Parent(); b.f(); //输出:Parent.f()
Child c = new Child(); c.f(); //输出:Child.f()
b = c; b.f(); //输出:Child.f()
(b as Parent).f(); //输出:Child.f()
第二节 通过实例理解多态
1、 多态编程:如果在编程时只使用基类和接口变量,而不使用具体的子类或实现接口的类,无疑就是一种“普遍性”的编程方式,会使代码具有更广的适合性。这种具有“普遍性”的编程方式,就是多态编程。
2、 多态编程的基本原理:使用基类或接口变量编程----依赖抽象编程,而不是依赖具体编程。
A、 基类一般都是抽象基类,其中拥有一个或多个抽象方法,各个子类可以根据需要重写这些方法。
B、 使用接口,为每个接口定义一个或多个方法,由实现接口的类根据实际需要提供这些方法的具体实现。
3、 多态的实现:继承多态和接口多态。
4、 小结:应用继承实现对象的统一管理,应用接口定义对象的行为特性。
第三节 协变与逆变
1、 协变:如果一个泛型接口(泛型委托)的类型参数前有一个out关键字,那么此类型参数可以接收子类型。 public interface IEnumerable<out T>:IEnumerable
{ Ienumerator<T> GetEnumerator(); }
IEnumerable<string> strings = ……;
IEnumerable<object> objects = strings;
2、逆变:如果一个泛型接口(泛型委托)的类型参数前有一个in关键字,那么此类型参数可以接收父类型。 Public delegate void Action<in T>(T obj);
Static void ParentFunc(Parent p) {}
Action<Child> del = ParentFunc;
3、 协变与逆变特性同样适合于非泛型的委托。
Public delegae Parent MyDelegate();
MyDelegate del = delegate(){
Return new Child();}