linq学习笔记(1):c#3.0新特性(2)

    4.       Object and Collection Initializers (对象和集合初始器)

    Object Initializer (对象初始器) ,顾名思义就是一种初始化对象的方式,这个“器”并非某个具体的类或者方法。
    
假设我们有一个用于个人信息的数据类,如下所示:
     public   class  Person
    {
        
public   int  UserID {  get set ; }
        
public   int  UserAge {  get set ; }
        
public   string  UserName {  get set ; }
}
    这个数据类只用于在内存中保存用户信息的用途,那么如果是以往,我们是这样初始化它的,首先我们可以生成一个实例,然后把各个属性值一一赋给这个实例对象,或者如果这个类的属性数量不算多,我们也可以提供一个包含所有属性的构造函数,这样我们只要在实例化的时候就可以把预先知道的属性值赋给这个对象。这是过去的老方法。下面看看 C# 3.0 给我们带来了新的对象初始器,那么新在哪里呢?请看下面一行代码:
Person person  =   new  Person { UserID  =   1 , UserAge  =   29 , UserName  =   " peida "  };
    在不需要提供任何自定义构造函数的情况下,对象初始器可以让我们实现在创建类实例的时候就对它进行初始化,可以想象一下对象初始器为我们节省了多少编写自定义构造函数的工作量。对象初始化器由一系列成员对象组成,其对象必须初始化,用逗号间隔,使用 {} 封闭。
    
例如,我把二个 Person 加到一个基于泛型的类型为 Person PersonList 集合中:

            IList < Person >  PersonList  =   new  List < Person >  
            { 
                
new  Person { UserID  =   1 , UserAge  =   29 , UserName  =   " peida "  }, 
                
new  Person { UserID  =   2 , UserAge  =   35 , UserName  =   " bamboo "  }
            };
    有相同名字和类型的两个对象初始化器将会产生相同的实例,可以相互赋值 , 例如:

            Person person1  =   new  Person { UserID  =   1 , UserAge  =   29 , UserName  =   " peida "  };
            Person person2 
=   new  Person { UserID  =   2 , UserAge  =   35 , UserName  =   " bamboo "  };
            person2 
=  person1;
    除了在初始化类时设置简单的属性值外,对象初始化器特性也允许我们设置更复杂的嵌套 (nested) 属性类型。例如我们可以在上面定义的 Person 类型同时拥有一个属于 Address 类型的叫“ Address ”的属性,首先我们建一个地址类,存放个人的地址信息,如下:

public   class  Address
    {
        
public   string  CityName {  get set ; }
        
public   string  PostCode {  get set ; }
    }
    然后在 Person 类中添加地址属性 , 如下:

     public   class  Person
    {
        
public   int  UserID {  get set ; }
        
public   int  UserAge {  get set ; }
        
public   string  UserName {  get ;   set ; }

        
private  Address useraddress  =   new  Address();
        
public  Address UserAddress
        {
            
get  {  return   useraddress; }
            
set  { useraddress  =  value; }
        }
    }
    接下来我们实例化 Person 类:

Person person1  =   new  Person {UserID = 1 ,UserAge = 89 ,UserName = " peida " , UserAddress  =  { CityName  =   " 北京 " , PostCode  =   " 100001 "  } };
    也可以这样实例化:

Person person2  =   new  Person { UserAddress = {CityName = " 北京 " ,PostCode = " 100001 " }};
    这一次我们初始化时省略了其它 3 个属性,因为对象初始器并不要求开发人员如果使用它就必须一次性对所有属性进行初始化。
    
Collection Initializer (集合初始器): 就是在实例化集合类的时候采用的一种新的初始化方式。集合初始化器由一系列集合对象组成,用逗号间隔,使用 {} 封闭。集合初始化器可以简化把几个对象一起添加到一个集合,编译器会自动为你做集合插入操作。例如:

List < string >  WeekDay  =   new  List < string >  {  " 周日 " " 周一 " " 周二 " " 周三 " " 周四 " " 周五 " " 周六 "  };
    对象与集合初始化器要点:对象初始化器实际上利用了编译器对对象中对外可见的字段和属性进行按序赋值。;对象初始化器允许只给一部分属性赋值,包括 internal 访问级别;对象初始化器可以结合构造函数一起使用,并且构造函数初始化先于对象初始化器执行;集合初始化器会对初始化器中的元素进行按序调用 ICollection<T>.Add(T) 方法;注意对象初始化器和集合初始化器中成员的可见性和调用顺序;对象与集合初始化器同样是一种编译时技术。
    
5.       Extension Methods (扩展方法)
    
扩展方法是一种开发人员轻松快捷地扩展已有类型的方法定义和实现的机制。扩展方法能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。
    
首先,扩展方法必须是静态方法,例如下面的代码的是扩展 string 类型,使其拥有直接将 string 类型转换成 decimal int 类型的方法,代码如下:


      public   static   class  ExtensionMethod   
     { 
         
public   static   decimal  ToMoney( this   string  money)   
         {   
             
decimal  number  =  0m; 
             
if  ( ! decimal .TryParse(money,  out  number)) 
             {  
                 
throw   new  ArgumentException( " Money Error Information. " );  
             } 
             
return  number;     
         }  
         
public   static   int  ToAge( this   string  age)  
         {  
             
int  number  =   0 ;  
             
if  ( ! int .TryParse(age,  out  number)) 
             { 
                 
throw   new  ArgumentException( " Age Error Information. " ); 
             }  
             
return  number; 
         }  
     }
    其调用方法如下:

             string  strInpurtMoney  =  Console.ReadLine();
            
decimal  UserMoney  =  strInpurtMoney.ToMoney();
            
string  strInpurtAge  =  Console.ReadLine();
            
int  UserAge  =  strInpurtAge.ToAge();
    我们很轻松地就为字符串增加了两个可能在实际项目中常常需要用到的方法,同时扩展方法还传承了 C# 简洁高雅的语法传统。
    如上所示,扩展方法必须是静态的,因此 static 关键字是少不了的,扩展方法只能在非泛型或非嵌套的静态类中声明,它是通过关键字 this 作为其第一个参数的修饰符来声明,它的第一个参数除了 this 关键字以外可以没有别的修饰符,同时这个参数不能是指针类型。扩展方法具备和常规静态方法一样的能力。
    扩展方法要点:
    扩展方法的本质为将实例方法调用在编译期改变为静态类中的静态方法调用。事实上,它确实拥有静态方法所具有的所有功能;扩展方法的作用域是整个 namespace 可见的,并且可以通过 using namespace 来导入其它命名空间中的扩展方法;扩展方法的优先级:现有实例方法优先级最高,其次为最近的 namespace 下的静态类的静态方法,最后为较远的 namespace 下的静态类的静态方法;扩展方法是一种编译时技术,注意与反射等运行时技术进行区别,并慎重使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值