Class ObjectA
 {
   ...............   //省略
 }Class Program
{
     public void MethodTestA(ref ObjectA obja){......}
     public void MethosTestB(    ObjectA obja){......}
     /************************ 两个方法中方法体一致 ***************************/  
}
假设两个方法中代码执行速度一致,据说调用MethodA时比MethodB执行的快。请各位大侠帮分析分析
public void MethodTestA(ref ObjectA obja){......} 
相当于 C++ 中
public void MethodTestA(ObjectA * obja)  {......} 

解决方案 »

  1.   

    方法a是直接传对象o的引用,可改变对象o的值
    方法b是复制一个o传进去,若对象o构造函数比较耗时,当然方法a比方法b快了
      

  2.   

    比如说
    1.
          ObjectA obja = new ObjectA();   //构造时间相同
          MethodTestA(ref obja);
    2.      ObjectA obja = new ObjectA();   //构造时间相同
          MethodTestB(obja);据说1比2执行快
      

  3.   

    比如说 
    1. 
          ObjectA obja = new ObjectA();  //构造时间相同 
          MethodTestA(ref obja); 
    2.       ObjectA obja = new ObjectA();  //构造时间相同 
          MethodTestB(obja); 
    ==MethodTestA(ref o1)
    如果是按引用传递,obja就是o1MethodTestB(o2)
    引用本身是按值传递,obja和o2事实上在堆里是两个不同的变量,但他们存放的内容相同,都是指向堆里同一变量的地址
      

  4.   

    引用本身是按值传递,obja和o2事实上在里是两个不同的变量,但他们存放的内容相同,都是指向堆里同一变量的地址
      

  5.   

    可能MethodTestA 比 MethodTestB 少分配了一块空间所以速度快些。哈哈
      

  6.   

    ref object可以更改object本身,比如传进去一头猪,传出来一头牛,而没有ref 则不可以,最多传进去一头活猪,出来的时候变成了死猪
      

  7.   

    class本身就是引用类型,2个方法速度应该一样
      

  8.   

    还真没啥奇怪的地方任何一个学过c++的都知道:*p,&p是啥区别为啥要这么设计,很简单!为了安全和灵活&p是为了安全
    *p是为了灵活so 我们多数情况下用&p,但少数情况我需要灵活就用*p
      

  9.   

    比如说 
    1. 
          ObjectA obja = new ObjectA();  //构造时间相同 
          MethodTestA(ref obja); 
    2.       ObjectA obja = new ObjectA();  //构造时间相同 
          MethodTestB(obja); 
    == MethodTestA(ref o1) 
    如果是按引用传递,obja就是o1 MethodTestB(o2) 
    引用本身是按值传递,obja和o2事实上在堆里是两个不同的变量,但他们存放的内容相同,都是指向堆里同一变量的地址简单的说就是引用与传值如何理解,慢慢领会吧!
      

  10.   

    public void MethosTestB(    ObjectA obja){......} 栈            堆
    obja---> ObjectA实例传入的参数是obja的值,也即一个ObjectA实例的地址,有了这个地址就可以修改这个ObjectA实例,
    但是无法修改实参obja的指向,无论如何,实参obja总是指向这个ObjectA实例
    public void MethodTestA(ref ObjectA obja){......} 
     
    栈         栈            堆
    &obja--->obja---> ObjectA实例传入的参数实际上是obja的地址,而obja其实是个指针,指向一个ObjectA实例
    有了这个地址,不但可以修改ObjectA实例,也可以修改实参obja,使它指向其他地方
    类似C语言的二级指针,但是在访问ObjectA实例的语法上却简化了,像是普通引用一样访问就可以了,这也是容易让人费解的地方
      

  11.   

    在C#中,方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by array)。传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。
      

  12.   

    ref用于將值類型的變量作為引用傳遞,但是public void MethodTestA(ref ObjectA obja){......} 中ObjectA本身就是引用類型變量,所以在這里實際上是對ObjectA地址的復制傳送,作用同public void MethosTestB(    ObjectA obja){......} 一樣,只不過前者在stack中多占據了4個字節的空間用于指向存儲ObjectA的地址的引用地址
      

  13.   

    两个方法的参数都是引用类型啊,
    应该一样快,不过obja要先初始化。
      

  14.   

    可能MethodTestA 比 MethodTestB 少分配了一块空间所以速度快些。哈哈
    ?Following is the jitted assembly for calling A(o) and B(ref o). 
    We can see A(o) moves the reference into register ECX,(.net uses fastcall)
    while B(ref o) moves the address of the reference into the register ECX.So, what is the speed difference?
    using System;
    class Program
    {
      static void Main()
      {
        object o = new Program();
        int i = 3333;            //BF050D0000     mov    edi,0D05h    A(o);                    //8B4DC0         mov    ecx,dword ptr [ebp-40h]
                                 //E8A3BFB2FF     call   0091C060 (ConsoleApplication1.Program.A(System.Object), mdToken: 06000002)    B(ref o);                //8D4DC0         lea    ecx,[ebp-40h]
                                 //E8AABFB2FF     call   0091C070 (ConsoleApplication1.Program.B(System.Object ByRef), mdToken: 06000003)
      }
      static void A(object o)
      {
      }
      static void B(ref object o)
      {
      }
    }
      

  15.   

    public void MethodTestA(ref ObjectA obja){......} 
    相当于 C++ 中 
    public void MethodTestA(ObjectA * obja)  {......} 
    ========================================================
    object obja 相当于 object* obja
    ref object obja 相当于 object** obja
      

  16.   


    你没有想过struct里面的this是什么吗,告诉你是ref struct 所以ref的设计是非常有意义的
      

  17.   

    ref ObjectA obja是不是先要有初始化的动作
      

  18.   

    使用ref后,在函数里面修改的数据在函数外面同样显示,也就相当于全局变量的效果,不使用ref只是局部变量
      

  19.   

    12楼的很经典的讲解。呵呵
    基本就是这样了
    ref传的是你开始定义的参数的引用,你操作该参数的时候只在该参数里面改变值。
    不加ref传的是值,要操作该参数,你需要重新分配内存空间。
    所以,第二种方法应该慢一点。
    在下拙见。
      

  20.   

    按引用传递值类型(如上所示)是有用的,但是 ref 对于传递引用类型也是很有用的。这允许被调用的方法修改该引用所引用的对象,因为引用本身是按引用来传递的。下面的示例显示出当引用类型作为 ref 参数传递时,可以更改对象本身。  复制代码 
    class RefRefExample
    {
        static void Method(ref string s)
        {
            s = "changed";
        }
        static void Main()
        {
            string str = "original";
            Method(ref str);
            // str is now "changed"
        }
    }
     来源MSDN
      

  21.   

    class Program
        {        
            static void Main()
            {
                Test test1 = new Test();
                test1.Str = "AAAAAAAAAAAAA";
                Test test2 = new Test();
                test2.Str = "BBBBBBBBBBBBB";            TestMethod(test1);
                TestMethod(ref test2);            Console.WriteLine("test1 : " + test1.Str);
                Console.WriteLine("test2 : " + test2.Str);
            }               static void TestMethod(Test test)
            {
                test = new Test();
            }        static void TestMethod(ref Test test)
            {
                test = new Test();
            }
        }    class Test
        {
            private String str;
            public String Str
            {
                get { return str; }
                set { str = value; }
            }
        }
    输出结果是:
          test1: AAAAAAAAAAAA
          test2:
      

  22.   

    class RefExample
    {
        static void Method(ref int i)
        {
            i = 44;
        }
        static void Main()
        {
            int val = 0;
            Method(ref val);
            // val is now 44
        }
    }
    class RefExample
    {
        static void Method(ref int i)
        {
            i = 44;
        }
        static void Main()
        {
            int val = 0;
            Method(ref val);
            // val is now 44
        }
    }ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。