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) {......}
{
............... //省略
}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) {......}
方法b是复制一个o传进去,若对象o构造函数比较耗时,当然方法a比方法b快了
1.
ObjectA obja = new ObjectA(); //构造时间相同
MethodTestA(ref obja);
2. ObjectA obja = new ObjectA(); //构造时间相同
MethodTestB(obja);据说1比2执行快
1.
ObjectA obja = new ObjectA(); //构造时间相同
MethodTestA(ref obja);
2. ObjectA obja = new ObjectA(); //构造时间相同
MethodTestB(obja);
==MethodTestA(ref o1)
如果是按引用传递,obja就是o1MethodTestB(o2)
引用本身是按值传递,obja和o2事实上在堆里是两个不同的变量,但他们存放的内容相同,都是指向堆里同一变量的地址
*p是为了灵活so 我们多数情况下用&p,但少数情况我需要灵活就用*p
1.
ObjectA obja = new ObjectA(); //构造时间相同
MethodTestA(ref obja);
2. ObjectA obja = new ObjectA(); //构造时间相同
MethodTestB(obja);
== MethodTestA(ref o1)
如果是按引用传递,obja就是o1 MethodTestB(o2)
引用本身是按值传递,obja和o2事实上在堆里是两个不同的变量,但他们存放的内容相同,都是指向堆里同一变量的地址简单的说就是引用与传值如何理解,慢慢领会吧!
obja---> ObjectA实例传入的参数是obja的值,也即一个ObjectA实例的地址,有了这个地址就可以修改这个ObjectA实例,
但是无法修改实参obja的指向,无论如何,实参obja总是指向这个ObjectA实例
public void MethodTestA(ref ObjectA obja){......}
栈 栈 堆
&obja--->obja---> ObjectA实例传入的参数实际上是obja的地址,而obja其实是个指针,指向一个ObjectA实例
有了这个地址,不但可以修改ObjectA实例,也可以修改实参obja,使它指向其他地方
类似C语言的二级指针,但是在访问ObjectA实例的语法上却简化了,像是普通引用一样访问就可以了,这也是容易让人费解的地方
应该一样快,不过obja要先初始化。
?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)
{
}
}
相当于 C++ 中
public void MethodTestA(ObjectA * obja) {......}
========================================================
object obja 相当于 object* obja
ref object obja 相当于 object** obja
你没有想过struct里面的this是什么吗,告诉你是ref struct 所以ref的设计是非常有意义的
基本就是这样了
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
{
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:
{
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 关键字。