比如我们写 a = b + 1; 这个代码保证 b 不被修改,这就给别人带来的安慰。而你的所谓“前辈”看来喜欢逃避责任,他一定要告诉你 b 被改变了然后让你猜改变成了什么。
ref是传递参数的地址,ref 传递参数前,必须先对变量初始化(赋值) 好处嘛,大概就不用做一件事情还没完,就要返回值给变量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 传参可能会略略提升性能,但是性能与语义相比意义不大。在.net类库里,ref 和 out 的使用是非常少的(out 与 ref 很相似)。有些值类型的 Parse 方法用到 out,而用到 ref 的我一时只能想到 InterLocked.Increment,我们可能要针对同一个 int 多次调用 Increment,因此这个 ref 的使用是合理的。这两个是使用 ref 和 out 的典型场景,而这两个场景并不常见。如果代码里到处充斥着 ref,那几乎可以肯定,这是前辈的陋习。
C#里的变量有值类型和引用类型的分别,而C++没有对此作明确的区分。C++中“真正的”对象,其语义和C#值类型相似。比如这个简单的代码void func(Student s) { s.name = "phil"; } Student st; func(st);调用之后,st.name 保持不变,原因是在调用函数时,编译器根据 st 的状态使用拷贝构造函数初始化了参数 s,函数体中的 s 与 st 是两个完全不同,可以独立改变而互不影响的对象。为了改变 st 的值,我们可以把形参声明为引用:void func(Student& s)或指针:void func(Student* s)C# 中的引用类型相当于指针方式,ref 修饰符则相当于引用方式。我们通常不会在一个参数上同时使用两种方式(即传递指针的引用 Student*&),因为那是多余的。可见C++中对引用的使用是有其语言背景的,将其照搬到C#可能是类型意识淡漠的表现。
有的时候也会用到ref,比如说返回值需要有多个的时候。当然是可以通过设计来避免的。尤其是方法内部需要修改参数是值类型的数据。void SetSomeSth(ref int result1, ref int result2)我自己很少用,主要是有悖于正常的习惯。关键是方法名一定要明确可懂,突出这个方法的作用。
传递到 ref 参数的参数必须最先初始化。 这与 out 不同,out 的参数在传递之前不需要显式初始化。 class RefRefExample { static void Method(ref string s) { s = "changed "; } static void Main() { string str = "original "; Method(ref str); // str is now "changed " } } class OutReturnExample { static void Method(out int i, out string s1, out string s2) { i = 44; s1 = "I 've been returned "; s2 = null; } static void Main() { int value; string str1, str2; Method(out value, out str1, out str2); // value is now 44 // str1 is now "I 've been returned " // str2 is (still) null; } }
没错,ref和out都是按地址传参,编译器对这两个关键字做了不同的限制,ref 参数在传参之前必须赋值,out参数在函数返回前必须赋值。因此,ref 是在提醒改变,而 out 则是承诺赋值
我哪敢怀疑,只是怀疑自己,第一次看见这么用ref的,多到你想不到
好处嘛,大概就不用做一件事情还没完,就要返回值给变量class RefExample
{
static void Method(ref int i)
{
i = 44;
}
static void Main()
{
int val = 0;
Method(ref val);
// val is now 44
}
}参考
费解。
我偶尔用。 这不好么?ref and out ??我的理解错误了?
这个我可没权力说接就接不接就不接,打工的,
其实本身我也有用过ref,但比较少,上个模块我写了1W行代码也就用了三四次,
前辈这里是一个类一大半的方法都用,我和我同事都很费解,如果多用好,那我
得好好学习。
不能一边倒的说不好。你贴一段代码来看看是否必要吧。
我猜测2个可能
1.的确需要这样写,因为要返回多个参数,但他不太了解面向对象的思路,没有创建类的习惯,其实返回多个参数的情况如果类似,可以吧返回多个结果写个类。可能都是返回结果不同但又需要返回多个参数?
2.可能是c/c++转来的,认为传递引用会快一些。给你建议一下,尽量少的重构他的代码,即便是很熟练c#的人,也会一不小心就出错的。因为不习惯这种写法,会有思考盲区的。
说明几点:
1、你的说法1:我很同意,我就喜欢将一些参数或者返回值封到一个类里(只要成员变数大的情况)
2、你的说法2:我和我同事也这么想,他是c转过来的,听说做c和c++的全是高手,所以我也不敢说什么
3、补充:我发这个贴最主要一点就是他用的ref多到无处不在,方法间又相互调来调去,本身主项目业务主挺烦人,但又没有一份文档支持,只是接解的人口头说
我也是第一次见那么喜欢用ref的程序员,方法之间调用多了,都不知道值在哪里改变了主要还是一点,有些参数用了ref从头到尾也没见重新赋个值,维护起来真吃力
C#里的变量有值类型和引用类型的分别,而C++没有对此作明确的区分。C++中“真正的”对象,其语义和C#值类型相似。比如这个简单的代码void func(Student s)
{
s.name = "phil";
}
Student st;
func(st);调用之后,st.name 保持不变,原因是在调用函数时,编译器根据 st 的状态使用拷贝构造函数初始化了参数 s,函数体中的 s 与 st 是两个完全不同,可以独立改变而互不影响的对象。为了改变 st 的值,我们可以把形参声明为引用:void func(Student& s)或指针:void func(Student* s)C# 中的引用类型相当于指针方式,ref 修饰符则相当于引用方式。我们通常不会在一个参数上同时使用两种方式(即传递指针的引用 Student*&),因为那是多余的。可见C++中对引用的使用是有其语言背景的,将其照搬到C#可能是类型意识淡漠的表现。
这与 out 不同,out 的参数在传递之前不需要显式初始化。 class RefRefExample
{
static void Method(ref string s)
{
s = "changed ";
}
static void Main()
{
string str = "original ";
Method(ref str);
// str is now "changed "
}
}
class OutReturnExample
{
static void Method(out int i, out string s1, out string s2)
{
i = 44;
s1 = "I 've been returned ";
s2 = null;
}
static void Main()
{
int value;
string str1, str2;
Method(out value, out str1, out str2);
// value is now 44
// str1 is now "I 've been returned "
// str2 is (still) null;
}
}
没错,ref和out都是按地址传参,编译器对这两个关键字做了不同的限制,ref 参数在传参之前必须赋值,out参数在函数返回前必须赋值。因此,ref 是在提醒改变,而 out 则是承诺赋值
让我感觉真有点像24楼说的一样,“关键是方法名一定要明确可懂,突出这个方法的作用”,但这个并不是很明确,返回值都不明确,几个参数进入一个方法,之间又是ref方法调用ref方法,哎。
现在我又有个关于调用web服务的问题,昨天找了一天资料也没找到一个感觉可以解决的办法:
http://topic.csdn.net/u/20101111/08/2a88883f-bdec-43d4-be34-69686b8901b9.html
路过的过去帮我看看,谢谢
sp1234老大说话一向说话都象机械工业出版社翻译的英文书,这就是sp(水平)。