用Ref和Out关键字的按引用传递比较分析:

     由上文《由String类型分析,所产生的对参数传递之惑的解答》 文,我们对值类型和引用类型,在用以关键字Ref传参时,所产生的可以导致原变量实现改变的结果进行了原因分析。然而用关键字Out的按引用传递(注:文中所说的"按引用传递",从英文翻译对号入座应为Ref,然而此处为了表示在传递时都传递的是参数的地址这一共性,故此处把按Ref关键字和按Out关键字传值,认为是按引用传递的两种方法。),在实现机理上可以达到和按Ref关键字传值完全相同的结果(这点从编译器所变异的代码是相同的这点得以验证!)。对此我们采用上文的测试环境,只对后台代码做适当修改,具体代码如下:

// 
   Description: 通过代码测试,比较Ref和Out关键字的按引用传递的区别

 
   // 
   CopyRight:  
    
   

 
   // 
   Notes: 环境是初始值为空的四个TextBox,前面的Lbel标签标示其作用
           
   // 
   按钮标示调用函数,并通过TextBox值显示对比效果 
   
 
   
 
   public 
     
   partial 
     
   class 
    ParaDelivery : System.Web.UI.Page
{
     
   protected 
     
   void 
    Page_Load( 
   object 
    sender, EventArgs e)
    {

    }
     
   protected 
     
   void 
    btnSubmit_Click( 
   object 
    sender, EventArgs e)
    {
         
   int 
    i  
   = 
     
   1 
   ;
         
   // 
   int i; 
   
 
            
   string 
    str  
   = 
     
   " 
   This is a String 
   " 
   ;
         
   // 
   string str; 
   
 
           txtItiValue.Text  
   = 
    i.ToString();
        txtRefValue.Text  
   = 
    str;
  
        AddValueType( 
   out 
      i);
        AddRefType( 
   out 
     str);
        txtChangedIntValue.Text  
   = 
    i.ToString();
        txtChangedRefValue.Text  
   = 
    str;
    }

     
   // 
   两个被调用函数 
   
 
        
   private 
     
   void 
    AddValueType( 
   out 
      
   int 
    funi)
    {
        funi 
   = 
   2 
   ;
    }
     
   private 
     
   void 
    AddRefType( 
   out 
      
   string 
    funStr)
    {
        funStr  
   = 
   " 
   This is a changed String 
   " 
   ;
    }
}


然而触发按钮事件的现实结果却完全如按Ref关键字的按引用传递结果,如下图示:

schemer传参 params传参_Text

 

即按Out传值实现了和按Ref传值的效果。然而就细节来说,它们还是具有不同点的,具体概括如下:

1.Out传递方法,可以在函数调用之前未赋值,而按Ref传值在函数调用之前必须要赋值的;

2.目的性不同:Out传递方法,顾名思义,Out主要是为从函数获取值的(因为按引用传递方法可以实现原变量的改变!),进而赋予原变量的,这是主要目的。而按Ref则不是这个目的存在的(它有可能是在调用函数中作为"右值",而并不是为了被更新)。我想这也是设计者针对两种情况分而设定的吧,呵呵~

 

用Params关键字传值:

     先看一演示示例。后台代码即环境布置见说明:


//    Description: 通过代码测试,说明Param关键字作用

    // 
   CopyRight:  
    
   

    // 
   Notes: 通过设置两个提交按钮——分别可以实现调用同一个函数,而同时其参数个数不同
    // 
    最后将结果反映在TextBox中 
   
    
    public 
     
   partial 
     
   class 
    ParamDelivery : System.Web.UI.Page
{
        protected 
     
   void 
    Page_Load( 
   object 
    sender, EventArgs e)
    {

    }
        protected 
     
   void 
    btnSubmit1_Click( 
   object 
    sender, EventArgs e)
    {
            int 
    i  
   = 
     
   1 
   , j  
   = 
     
   2 
   , k  
   = 
     
   3 
   ;
        txtDisplaySum.Text     = 
    AddParamSum(i, j, k).ToString();
    }
        protected 
     
   void 
    btnSubmit2_Click( 
   object 
    sender, EventArgs e)
    {
            int 
    i  
   = 
     
   1 
   , j  
   = 
     
   2 
   , k  
   = 
     
   3 
   , l  
   = 
     
   4 
   , m  
   = 
     
   5 
   ;
        txtDisplaySum.Text     = 
    AddParamSum(i, j, k, l, m).ToString();
    }
        // 
   公共调用函数,实现参数的相加功能 
   
         
   private 
     
   int 
    AddParamSum( 
   params 
     
   int 
   [] arrParam)
    {
            int 
    sum  
   = 
     
   0 
   ;
            for 
    ( 
   int 
    i  
   = 
     
   0 
   ; i  
   < 
    arrParam.Length; i 
   ++ 
   )
        {
            sum     += 
    i;
        }
            return 
    sum;
    }
}


当分别触发按钮1(btnSubmit1)和按钮2(btnSubmit2),所产生结果见下图示:

schemer传参 params传参_ui_02

 

schemer传参 params传参_引用传递_03

 

可见他们都实现了对各自参数的相加功能,这比使用重载的Add函数要简便的多(况且适应性更强了)。Params的实现机理即是通知编译器要将传递过来参数,包装成数组来处理。

附:在使用Params时注意事项:

1.Params所修饰的只能为一维数组;

2.Params可以修饰任何类型,将函数中类型定义为 Object;

3.在函数中,Params项必须置于最后位置;

 

综述之,作为对参数传递的补充部分,这里比较了按Ref关键字和按Out关键字的按引用传递,以及C#所提供的对于不定项数组的"智能方法"——Params关键字使用。至此对参数传递相关知识又做了一次回顾,呵呵