在C#中使用REF和OUT关键字传递和传递值目前我的理解是这样的:Passingbyvaluebyvalue意思是传递参数的副本。对此副本的更改不会改变原始副本。通过引用传递意味着传递对原始文件的引用。对参考的更改会影响原始参考。REF关键字REF告诉编译器在进入函数之前初始化对象。REF表示该值已经设置,因此该方法可以读取和修改它。REF以两种方式工作,包括输入和输出。OUT关键字OUT告诉编译器该对象将在函数内初始化。OUT表示还没有设置值,所以必须在调用return之前设置。OUT只是一种方式,就是滚出去。Question那么在什么情况下你会结合ref和out关键字,按引用传递还是按值传递?例子会有很大帮助。太感谢了。您永远不会在1个参数上组合ref和out。它们都表示“通过引用传递”。您当然可以在一个方法中组合ref参数和out参数。ref和out之间的区别主要在于意图。ref信号双向数据传输,out表示单向。但除了意图之外,C#编译器会跟踪明确的赋值,这是最显着的区别。它还可以防止误读(读取)out参数。voidSetOne(outintx){inty=x+1;//错误,'x'未明确分配。x=1;//强制赋值}voidAddTwo(refintx){x=x+2;//好的,已知x已分配}voidMain(){intfoo,bar;SetOne(输出foo);//好的,不必为foo赋值AddTwo(reffoo);//OK,foo由SetOneAddTwo(refbar)赋值;//error,barisunassigned}非常感谢通过正确和仔细地使用语言,你的理解将会提高。按值传递意味着传递参数的副本。是的,这是完全准确的。对此副本的更改不会改变原始副本。不完全的。首先仔细区分值和变量。考虑:classFoo{publicintx;}...voidN(){Fooblah=newFoo();blah.x=0;M(废话);}...voidM(Foofoo){foo.x=123;//改变blah.xfoo=null;//不改变blah}这里的变量是x,blah和foo。x是字段,blah是局部的,foo是表单参数。这里的值是null,0,123,以及对Foo实例的引用。引用是一个值。了解这一事实至关重要。通过将变量blah的值复制到变量foo来传递blah值的副本。blah的值是对Foo实例的引用。M可以更改变量x的值,因为M有blah值的副本,它是对Foo的引用。当M将foo的内容更改为null时,这并没有改变blah;foo包含blah值的副本。通过引用传递意味着传递对原始文件的引用。仔细选择你的措辞。什么是“原始”?这将更好地表述为“通过引用传递意味着传递对参数的引用,该参数必须是一个变量”。考虑它的一种更简单的方法是“通过引用传递使参数成为作为参数传递的变量的别名”。对参考的更改会影响原始参考。由于arguments和arguments是彼此的别名,因此对引用的更改不会影响原始arguments;参考文献为原文。它们都是同一个变量。REF告诉编译器在进入函数之前初始化对象。“对象”没有任何意义。你的意思是“变量”。“ref”不会“告诉编译器变量已经初始化”。相反,“ref”告诉编译器“你,编译器,必须验证变量是否已经初始化”。那是完全不同的!REF表示设置了值,不,ref需要设置变量。没有“设定值”这样的东西。因此,该方法可以读取和修改它。“它”的意思是“变量”。REF以两种方式工作,包括输入和输出。正确的。OUT告诉编译器该对象将在函数内部初始化。停止使用“对象”来表示“变量”。如果你不再混淆完全不同的事物,你会更清楚地理解事物。变量不是对象。变量是存储位置,其中一些可能包含值,其中一些可能是对对象的引用。所以out告诉编译器变量将在方法内部初始化,是的,但这并不完全正确。您忘记了方法会抛出异常的情况,或者方法会进入无限循环的情况——这些也是合法的情况。OUT表示该值尚未设置,同样,“值”是指“变量”。但这并不准确。将初始化变量作为“out”参数传递是完全合法的。毫无意义,但合法。因此必须在调用返回之前设置它。没有所谓的“回归”;该方法被调用。但是,是的,该方法必须在正常返回之前为变量赋值。OUT只是一种方式,就是滚出去。正确的。那么什么情况下会把ref和out关键字结合起来呢,没有这种场景。无论哪种方式,您都了解动态。一些参数场景可能是:通常,当函数必须返回多个值时,输出参数是合适的,因为函数只有一个返回值(尽管它可以是复合值)。有时,数据访问提供程序(例如某些ADO.NET方法)使用输出参数来传递信息。一些数据访问方法模仿具有输入/输出参数的数据库存储过程。编辑:引用类型的一项规定是参数refStringBuilderword或StringBuilderword(按值)表现相同-外部字符串受到影响,尽管底层实现可能略有不同,因为此时重点是引用而不是堆上的值。编辑:我已经更正了这个答案,以反映C#中的“out”关键字没有达到预期的效果(就像计算机科学意义上的真正OUT参数)。我最初声称“out”是由OUT值传递的,但事实证明这是错误的。您不能同时使用“out”和“ref”。C#(.NETFramework)中存在三种调用约定:C#没有真正的OUT或IN-OUT参数功能。要查看C#中的“out”参数并不是真正的OUT参数,您可以使用以下代码:publicclassTest{Action_showValue;publicvoidRun(){stringlocal="Initial";_showValue=()=>{控制台。WriteLine(local.ToString());};Console.WriteLine("按值传递");在方法(本地);Console.WriteLine("使用'out'关键字通过引用传递");outMethod(出本地);.WriteLine("使用'ref'关键字通过引用传递");refMethod(参考本地);}voidinMethod(stringarg){_showValue();参数="IN";_showValue();}voidoutMethod(outstringarg){_showValue();参数=“输出”;_showValue();}voidrefMethod(refstringarg){_showValue();arg="REF";_showValue();}}输出为:按值传递InitialInitial使用“out”关键字按引用传递InitialOUT使用“ref”关键字按引用传递OUTREF如您所见,“out”和“ref”实际上都传递了REF。唯一的区别是编译器如何将它们视为明确的分配目的。如果您有一个需要返回多个值的方法,则使用OUT关键字很有用。例如,查看int.TryParse()等方法。使用REF更多是关于对象的明确性。请记住,传递到方法中的任何非基元都是通过引用传递的,这在普通托管代码中是不需要的。通过声明REF关键字,您声明可以在方法主体中修改参数,因此调用代码应该知道它(因此您也必须在调用代码中显式添加ref。如果您了解C++,这可能对你有用有帮助:voidFoo(Bar){}//按值传递c#(如果它是值类型;))voidFoo(Bar){}//c++voidFoo(Bar){}//按引用传递c#(如果它是引用类型;))voidFoo(Bar&){}//c++voidFoo(refBar){}//c#voidFoo(Bar*)//c++voidFoo(outBar){}//c#voidFoo(Bar**){}//c++(*Bar的内容需要补上)你通过ref传递你想要被另一个函数读写的东西,所以你应该把初始化变量传递给填写正确阅读。编辑:示例:voidmymethod(refinta){a++;你正在传递一些你想要由另一个函数写入的东西,但你不需要初始化它,因为它不会被函数读取,只会被写入回车。编辑:范例:以上是C#学习教程:使用REF和OUT关键字传值,C#传值,分享全文。如果对大家有用,需要进一步了解C#学习教程,希望大家多多指教。}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
