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();}