C#中c语言多线程参数传递传递参数能用ref吗

c#中ref和out参数使用时需要注意的问题
c#中ref和out参数使用时需要注意的问题,c#中ref和out参数使用时需要注意的问题
昨天写了个关于socket接收udp包的程序,调用了socket.ReceiveFrom方法,发现了一个c#中关于ref和out参数传递时的问题,这里提出来和大家共同探讨一下,首先声明,下面的结论都是本人推测,还没有得到任何定论,若有错误请大家指正。首先,ReceiveFrom方法的原型为 public int ReceiveFrom(byte[], ref EndPoint); 有一个为ref的EndPoint参数,用它来返回收到包的源地址信息,ref的语义是传引用,即对所传引用的修改可以反映到方法外面。我一般都使用IPEndPoint来表示地址信息,所以很自然的使用了如下的调用方法 (代码1) IPEndPoint iep = new IPEndPoint(IPAddress.Any,0); socket.ReceiveFrom(buffer,ref (EndPoint)iep);这时编译时出现了一下的错误,ref或out参数必须是一个lvalue,iep怎么会不是一个左值呢?关键是在调用方法时使用的强制转换(例如(EndPoint)iep),我改了一下代码 (代码2)IPEndPoint iep = new IPEndPoint(IPAddress.Any,0); EndPoint ep = (EndPoint) socket.ReceiveFrom(buffer,ref (EndPoint)iep);这次通过编译了。为什么在方法调用时会出问题?这里要考虑类型强制转换时的一个细节,强制转换时编译器会先生成一个临时引用,然后再把这个临时引用传给一个和转换类型相同的引用,这个临时引用比较特别不是一个左值(lvalue),不能被赋值!而使用ref参数的方法一般都要对这个引用做修改,如果直接把这个临时引用传进去当时编译器会抱怨ref或out参数必须是一个lvalue。而代码2首先将这个临时引用赋值到一个常规引用上去,这时这个常规引用便是可以复制的了。
来源:/n/9051.html
热门搜索:
照片PS 调出浪漫情侣色教程
CAD教程 怎么使用CAD画图形
电脑复选框如何开启
使用PS扭曲工具减肥瘦脸方法
因为对于孩子来说,自闭症是影响一生的疾病,所以很多父母对于自闭症会有一下了解,但是父母对于自闭症的危害却不是非常了解,下面就给父母们介绍一下自闭症对于孩子有哪些危害。
自闭症对于孩子来说是一种非常恐怖的心理疾病,这种疾病若是不及时治疗会影响孩子一辈子,但是很多人没有发觉到自闭症孩子的一些异常,下面就给大家介绍一下自闭症的症状。
随着人们年龄的增长,冠心病的患病率的几率越来越高,很多人知道了自己冠心病,只不过很多人不知道怎么调养,下面就给各位详细的介绍一下冠心病应该注意哪些问题。
随着人们的医疗知识的普及,现在一到暑假的时候,医院里面一个医生一天割包皮要割几十个,但是,很多人想让自己尽快恢复过来,这就要靠调养了,下面就给大家介绍一下包皮术后的调养。
微博是我们现在相当流行的社交软件,现在大家也很喜欢用表情包进行交流,也已经成为了一种流行文化。最近微博也出了一组很可爱的表情包,下面就给大家来介绍微博新出的表情有哪些吧。
今日北京时间凌晨苹果召开新品发布会,iPhone 7和iPhone 7 Plus正式登台亮相,中国在首发之列,iPhone7起售价为5388元,iPhone7 Plus起售价为6388元,iphone7各项性能创新升级也让那些果粉们早就跃跃欲试了吧,而此次中国大陆的iPhone 7/7 Plus将在9月9日下午3:01正式开启预售,9月16日将正式开卖。现在万事俱备,只欠“割肾”,果粉们,Are you ready?
火影是笔者非常喜欢的一个动漫,同时火影的游戏也有很高的可玩性,对于新手玩家首先要了解火影忍者究极风暴3出招表,下面我就来教大家这款游戏里一些招式,喜欢这个游戏的玩家不妨来看看。
肚子上的赘肉看上去让人烦恼,尤其是对于想穿裙子的女生来说更是一件郁闷的事情。现在减肥的方法有很多,但是很多人并不知道专门瘦肚子的方法。那么,如何瘦肚子呢?下面就给大家介绍几种减肚子的方法吧。
炎夏烈日炎炎,就在你与阳光亲密接触时,也让紫外线有了可乘之机,有的时候,虽然你认真做了防晒的工作,却依旧没能躲过炙热的阳光,晒伤之后,要立马着手修复晒伤的肌肤,那么晒伤后怎么处理呢?下面就一起来看看吧。
脸上肉嘟嘟的女生和男生们是不是选择发型的时候很伤大脑。没关系,我们这里肯定有一款适合你的发型,本文也是大圆脸一枚,下面分享下我收集多年的圆脸女生男生发型以及学会的圆脸发型修饰技巧。
如果您有什么好的建议或者疑问,可以联系我们! QQ群: QQ号: 进群、加好友,备注:图老师 小周老师一一为您解答!让我们一起学习、一起进步 版权所有 (C) 2016 All Rights Reserved. 湘ICP备号
微信公众号C#方法参数传递-同时使用ref和out关键字 - 流星落 - 博客园
随笔 - 512, 文章 - 0, 评论 - 2, 引用 - 0
在方法参数传递中,可以同时使用ref和out关键字,但是要注意ref和out参数传递的不同。
using Sclass Program{static void Main(){&&& Program obj = new Program();&&& int score = 55; //声明原来分数&&& int refscore, //声明两个变量&&& obj.ChangeScore(score, ref refscore, out outscore);&&& Console.WriteLine("您原来的分数是{0},调整后的分数为{1},加平时表现分后{2}",&&&&& score, refscore, outscore);&&& Console.ReadKey();}private void ChangeScore(int score, ref int refscore, out int outscore){&&& if (score & 50 && score & 60)&&& {&&&&& refscore = 60;&&& }&&& if (refscore & 60)&&& {&&&&& outscore = refscore + 5;&&& }}}
以上代码编译时会出现两个错误,我们只声明了变量refscore,并没有给变量显示赋值。所以出现第一个错误:使用了未赋值的局部变量&refscore&。out关键字传递参数时,必须被调用方法内修改参数,用if语句判断,只有符合条件的out参数赋值,不符合条件的out参数没有赋值,所以出现了&控制离开方法之前必须对out参数outscore赋值&错误。
using Sclass Program{static void Main(){&&& Program obj = new Program();&&& int score = 55; //声明原来分数&&& int refscore = 0, //声明两个变量&&& obj.ChangeScore(score, ref refscore, out outscore);&&& Console.WriteLine("您原来的分数是{0},调整后的分数为{1},加平时表现分后{2}",&&&&& score, refscore, outscore);&&& Console.ReadKey();}private void ChangeScore(int score, ref int refscore, out int outscore){&&& if (score & 50 && score & 60)&&& {&&&&& refscore = 60;&&& }&&& if (refscore & 60)&&& {&&&&& outscore = refscore + 5;&&& }&&& else&&& {&&&&& outscore =&&& }}}
以下内容供参考:
一、值参数与引用参数及输出参数的区别:1、值参数中实参的值不随形参值变更而变更;形参与实参值互不影响,实参传递给形参时,栈中就为其分配另外一部分空间。这样,两个参数变更时而互不影响。2、引用参数及输出参数中实参的值会随形参值变更而变更;(形参:在定义函数中指定的形参,在未出现函数调用时,它们并不占内存中的存储单元。只有在发生函数调用时,函数中形参才被分配内存单元。在调用结束后,形参所占的内存单元也被释放。调用时将实参的值赋绐形参);引用参数与输出参数中,实参在栈中分配空间。当实参传递给形参时,会将地址传递给形参,即传送的指针,这样形参变更时,实参也会随著变更。
二、引用参数与输出参数区别:1、使用ref与out参数时,方法中参数及调用参数都需要加Ref或out关键字。2、使用ref参数与out参数得到的结果是一样的,区别是:ref在调用前需给调用方法中的参数赋初值。out在调用前不需给调用方法中的参数赋初值,参数在实际方法体中初始化。yvbang 的BLOG
用户名:yvbang
文章数:39
访问量:6842
注册日期:
阅读量:5863
阅读量:12276
阅读量:354556
阅读量:1051907
51CTO推荐博文
&值类型和引用类型的区别:
值类型(Value Type),值类型实例通常分配在线程的堆栈(stack)上,并且不包含任何指向实例数据的指针,因为变量本身就包含了其实例数据。
引用类型(Reference Type),引用类型实例分配在托管堆(managed heap)上,变量存储对值的内存地址的引用。
public&class&Test
static&void&Main()
//定义值类型和引用类型,并完成初始化
MyStruct&myStruct&=&new&MyStruct();
MyClass&myClass&=&new&MyClass();
//定义另一个值类型和引用类型,
//以便了解其内存区别
MyStruct&myStruct2&=&new&MyStruct();
myStruct2&=&myS
MyClass&myClass2&=&new&MyClass();
myClass2&=&myC&&&&&&&&
&&&&&&&&&&&&&
根据参数类型和传递方式不同,有以下4中不同的情况:
值类型参数的按值传递
引用类型参数的按值传递
值类型参数的按引用传递
引用类型参数的按引用传递
1.值类型的参数的按值传递
值类型实例传递的是该值类型实例的一个拷贝,因此被调用方法操作的是属于自己本身的实例拷贝,因此不影响原来调用方法中的实例值。
namespace&Anytao.net.My_Must_net
class&Args
public&static&void&Main()
&&&&&&&&&&&&
int&a&=&10;
&&&&&&&&&&&&
&&&&&&&&&&&&
Console.WriteLine(a);
//输出结果为10
private&static&void&Add(int&i)
&&&&&&&&&&&&
i&=&i&+&10;
&&&&&&&&&&&&
Console.WriteLine(i);&
2.引用类型参数的按值传递
当传递的参数为引用类型时,传递和操作的是指向对象的引用,这意味着方法操作可以改变原来的对象,但是值得思考的是该引用或者说指针本身还是按值传递的。
namespace&Anytao.net.My_Must_net
class&Args
public&static&void&Main()
&&&&&&&&&&&&
ArgsByRef&abf&=&new&ArgsByRef();
&&&&&&&&&&&&
AddRef(abf);
&&&&&&&&&&&&
Console.WriteLine(abf.i);
//输出结果为20
private&static&void&AddRef(ArgsByRef&abf)
&&&&&&&&&&&&
abf.i&=&20;
&&&&&&&&&&&&
Console.WriteLine(abf.i);
class&ArgsByRef
public&int&i&=&10;
按值传递的实质的是传递值,不同的是这个值在值类型和引用类型的表现是不同的:参数为值类型时,&值&为实例本身,因此传递的是实例拷贝,不会对原来的实例产生影响;参数为引用类型时,&值&为对象引用,因此传递的是引用地址拷贝,会改变原来对象的引用指向,这是二者在统一概念上的表现区别,理解了本质也就抓住了根源。
<span color="#.string类型作为引用类型的特殊性
namespace&Anytao.net.My_Must_net
class&Test&&&&
private int i = 10;
static&void&Main()
&&&&&&&&&&&&
string&str&=&&Old&String&;
&&&&&&&&&&&&&Test
&&&&&&&&&&&&
ChangeStr(str);
&&&&&&&&&&&&
ChangeObj(test);
&&&&&&&&&&&&
Console.WriteLine(str); //输出结果为Old String
&&&&&&&&&&&&
Console.WriteLine(test.i);
//输出结果为10
static void ChangeObj(Test t)
&&&&&&&&&&&&&t=new Test();
//这里将创建一个新的对象,所以改变它不会对原对象有影响
&&&&&&&&&&&&&t.i=20;
static&void&ChangeStr(string&aStr)
&&&&&&&&&&&&
aStr&=&&Changing&String&;
&&&&&&&&&&&&
Console.WriteLine(aStr);
下面对上述示例的执行过程简要分析一下:首先,string str = &Old
String&产生了一个新的string对象,然后执行ChangeStr(aStr),也就是进行引用类型参数的按值传递,我们强调说这里传递的是引用类型的引用值,也就是地址指针;然后调用ChangeStr方法,过程aStr
= &Changing String&完成了以下的操作,先在新的一个地址生成一个string对象,该新对象的值为&Changing
String&,引用地址为0x06赋给参数aStr,因此会改变aStr的指向,但是并没有改变原来方法外str的引用地址,
因此执行结果就可想而知,我们从分析过程就可以发现string作为引用类型,在按值传递过程中和其他引用类型是一样的。如果需要完成ChangeStr()调用后,改变原来str的值,就必须使用ref或者out修饰符,按照按引用传递的方式来进行就可以了,届时aStr
= &Changing String&改变的是str的引用,也就改变了str的指向。
4.按引用传递之ref和out
不管是值类型还是引用类型,按引用传递必须以ref或者out关键字来修饰,其规则是:
方法定义和方法调用必须同时显示的使用ref或者out,否则将导致编译错误;
namespace&Anytao.net.My_Must_net._11_Args
class&TestRefAndOut
static&void&ShowInfo(string&str)
&&&&&&&&&&&&
Console.WriteLine(str);
static&void&ShowInfo(ref&string&str)
&&&&&&&&&&&&
Console.WriteLine(str);
当然,按引用传递时,不管参数是值类型还是引用类型,按引用传递时,传递的是参数的地址,也就是实例的指针。ref和out关键字将告诉编译器,方法传递的是参数地址,而不是参数本身。
如果参数是引用类型,则按引用传递时,传递的是引用的引用而不是引用本身,类似于指针的指针概念。
Ref和Out的区别:
ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数,
可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:
1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。
2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。
3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。
注:在C#中,方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by
array)。传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。
方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。
传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。
属性不是变量,不能作为 ref 参数传递。
如果两种方法的声明仅在它们对 ref 的使用方面不同,则将出现重载。但是,无法定义仅在 ref 和 out 方面不同的重载。
方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。
若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。
不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。
属性不是变量,不能作为 out 参数传递。
网上有很多文章说ref
只传值,out传地址等等这种说法,好像不是非常的准确。以下是我做的实例代码,大家可以去试试:
&public int& RefValue(int
i,ref int j)
&&&&&&&&&&& int k =
&&&&&&&&&&& j
&&&&&&&&&&& return i+k;
&&&&&&& public int OutValue(int i, out int j)
&&&&&&&&&&& j = 222;
&&&&&&&&&&& return i +
&&&&&&& private void cmdRef_Click(object sender, EventArgs e)
&&&&&&&&&&& int m = 0;
&&&&&&&&&&& MessageBox.Show(RefValue(1, ref
m).ToString());
&&&&&&&&&&& MessageBox.Show(m.ToString());
&&&&&&& private void cmdOut_Click(object sender, EventArgs e)
&&&&&&&&&&&
&&&&&&&&&&& MessageBox.Show(OutValue(1, out
m).ToString());
&&&&&&&&&&& MessageBox.Show(m.ToString());
借网上总结的一句话说,ref是有进有出,而out是只出不进。
代码示例:
using System.Collections.G
using System.T
namespace Parameter
&&& class Program
&&&&&&& static void
Main(string[] args)
&&&&&&&&&&& Test1 test1 = new
&&&&&&&&&&& test1.MainClaee1();
&&&&&&&&&&& Test2 test2 = new Test2();
&&&&&&&&&&& test2.MainClass2();
&&&&&&&&&&& Test3 test3 = new Test3();
&&&&&&&&&&& test3.MainClaee3();
&&&&&&&&&&& Test4 test4 = new Test4();
&&&&&&&&&&& test4.MainClass4();
&&&&&&&&&&& Console.ReadKey();
&&& #region 值类型参数的按值传递
&&& class Test1
&&&&&&& public void
MainClaee1()
&&&&&&&&&&& int a = 1;
&&&&&&&&&&&
Change(a);
&&&&&&&&&&& Console.WriteLine(a + &\n&);
private static void Change(int b)
&&&&&&&&&&& b = b +
&&&&&&&&&&& Console.WriteLine(b);
&&& #endregion
值类型参数的按值传递
&&& #region 引用类型参数的按值传递
&&& class Test2
&&&&&&& public void
MainClass2()
&&&&&&&&&&& ArgsByRef abr = new
ArgsByRef();
&&&&&&&&&&& Change(abr);
&&&&&&&&&&& Console.WriteLine(abr.i
&&&&&&& private static void Change(ArgsByRef
&&&&&&&&&&& abr.i = 20;
&&&&&&&&&&&
Console.WriteLine(abr.i);
&&& class ArgsByRef
&&&&&&& public int i = 10;
#endregion 引用类型参数的按值传递
&&& #region string类型作为引用类型的特殊性
&&& class Test3
&&&&&&& private
int i = 10;
&&&&&&& public void MainClaee3()
&&&&&&&&&&&
string str = &Old Str&;
&&&&&&&&&&& Test3 test3 = new Test3();
&&&&&&&&&&&
Change(test3);
&&&&&&&&&&& ChangeStr(str);
&&&&&&&&&&&
Console.WriteLine(str);
&&&&&&&&&&& Console.WriteLine(i + &\n&);
&&&&&&& private static void Change(Test3 t)
&&&&&&&&&&& t = new Test3();
&&&&&&&&&&& t.i = 20;
&&&&&&& private static void ChangeStr(string str)
&&&&&&&&&&& str = &New Str&;
&&&&&&&&&&&
Console.WriteLine(str);
&&& #endregion
string类型作为引用类型的特殊性
&&& #region 按引用传递 ref和out
&&& class Test4
&&&&&&& public void
MainClass4()
&&&&&&&&&&& int i = 10;//&&
ref使用前,必须先赋值
&&&&&&&&&&& Console.WriteLine(&使用ref传值:&);
&&&&&&&&&&&
ChangeByRef(ref i);
&&&&&&&&&&& Console.WriteLine(i);
&&&&&&&&&&& int i2;
&&&&&&&&&&&
Console.WriteLine(&使用out传值:&);
&&&&&&&&&&& ChangeByOut(out
&&&&&&&&&&& Console.WriteLine(i2);
&&&&&&& private static void ChangeByRef(ref int i)
&&&&&&&&&&& i = 20;
&&&&&&&&&&& Console.WriteLine(i);
&&&&&&& private static void ChangeByOut(out int i)
&&&&&&&&&&& i = 30;
&&&&&&&&&&& Console.WriteLine(i);
&&& #endregion 按引用传递 ref和out
了这篇文章
类别:未分类┆阅读(0)┆评论(0)2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。c# wpf 中,一个控件事件能否用ref传递进去参数_c#吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:93,110贴子:
c# wpf 中,一个控件事件能否用ref传递进去参数收藏
c# wpf 中,一个控件事件能否用ref传递进去参数?
比如一个keydown事件
达内,19大热门编程语言:java/c++/web前端/php/html5/ios/android/嵌入式/软件测试等等,专业讲师授课,——在线咨询免费试学7天!
再包装一个独立函数用于调用即可
为什么要这么做?是不是有什么问题?
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或

我要回帖

更多关于 c 线程池参数传递 的文章

 

随机推荐