c#中out参数的用途是什么

你能告诉我out参数的确切用法吗?

相关问题:
ref和out有什么区别? (C#)

很好地使用out参数的最好例子是TryParse方法。

 int result =-1; if (!Int32.TryParse(SomeString, out result){ // log bad input } return result; 

使用TryParse而不是ParseInt消除了处理exception的需要,并使代码更加优雅。

out参数基本上允许来自方法的多个返回值。

方法参数上的out方法参数关键字使方法引用传递给方法的同一变量。 当控制传递回调用方法时,对方法中的参数所做的任何更改都将反映在该变量中。

当您希望方法返回多个值时,声明out方法很有用。 使用out参数的方法仍然可以返回值。 一个方法可以有多个out参数。

要使用out参数,必须将参数显式作为out参数传递给方法。 out参数的值不会传递给out参数。

作为out参数传递的变量无需初始化。 但是,必须在方法返回之前为out参数指定一个值。

一个例子:

 using System; public class MyClass { public static int TestOut(out char i) { i = 'b'; return -1; } public static void Main() { char i; // variable need not be initialized Console.WriteLine(TestOut(out i)); Console.WriteLine(i); } } 

http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx

Out参数仅输出参数,这意味着它们只能从函数中传回一个值。我们通过在参数数据类型前面加上out修饰符来创建一个“out”参数。 当传递“out”参数时,只将未分配的引用传递给函数。

 using System; class ParameterTest { static void Mymethod(out int Param1) { Param1=100; } static void Main() { int Myvalue=5; MyMethod(Myvalue); Console.WriteLine(out Myvalue); } } 

由于“out”参数的值被传递回调用部分,因此上述程序的输出将为100。 注意

修饰符“out”应该在即使在调用部分中传递的参数之前。 在为函数赋值之前,不能在函数内使用“out”参数。 在方法返回之前,应将值赋给“out”参数。

来自http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx

考虑参数的一种方法是它们就像方法的附加返回值。 当方法返回多个值时,它们非常方便,在本例中为firstName和lastName。 但是,可以滥用输出参数。 如果你发现自己编写了一个包含许多参数的方法,那么你应该考虑重构代码。 一种可能的解决方案是将所有返回值打包到单个结构中。

相比之下,ref参数被认为是被调用者最初分配的。 因此,被调用者在使用之前不需要分配给ref参数。 Ref参数传入和传出方法。

除了允许您具有多个返回值之外,另一个用途是在将大值类型复制到方法时减少开销。 当您将某些内容传递给某个方法时,会生成该内容的值的副本。 如果它是引用类型(例如字符串),则创建引用的副本(引用类型的值)。 但是,当您复制值类型(像intdouble这样的struct )时,会生成整个事物的副本( 值类型就是事物本身)。 现在,引用是4个字节(在32位应用程序上), int是4个字节,因此复制不是问题。 但是,可能有非常大的值类型,虽然不推荐,但有时可能需要它。 当你有一个64字节的值类型时,将它复制到方法的成本是高昂的(特别是当你出于性能原因使用这么大的struct )。 当你out ,没有对象的副本,你只需要引用相同的东西。

 public struct BigStruct { public int A, B, C, D, E, F, G, H, J, J, K, L, M, N, O, P; } SomeMethod(instanceOfBigStruct); // A copy is made of this 64-byte struct. SomeOtherMethod(out instanceOfBigStruct); // No copy is made 

直接与此一致的第二个用法是,因为你没有复制struct,而是在方法中引用与方法之外相同的东西,对方法内部对象所做的任何更改,在方法之外持久存在。 在引用类型中已经是这种情况,但在值类型中不是这种情况。

一些例子:

  public void ReferenceExample(SomeReferenceType s) { s.SomeProperty = "a string"; // The change is persisted to outside of the method } public void ValueTypeExample(BigStruct b) { bA = 5; // Has no effect on the original BigStruct that you passed into the method, because b is a copy! } public void ValueTypeExampleOut(out BigStruct b) { b = new BigStruct(); bA = 5; // Works, because you refer to the same thing here } 

现在,您可能已经注意到在ValueTypeExampleOut我创建了一个BigStructnew实例。 这是因为,如果你out ,你必须在退出方法之前将变量赋值给某个东西。

但是,另一个关键字ref是相同的,除了您不必在方法中分配它。 但是,这也意味着你不能传入一个未赋值的变量,这将使得与ref使用时不会编译好的Try ..模式。

 int a; if(TrySomething(out a)) {} 

这是有效的,因为TrySomething被迫分配给一些东西。

 int a; if(TrySomething(ref a)) {} 

这不起作用,因为a是未分配的(刚刚声明),而ref要求您只将它与指定的变量一起使用。

这是有效的,因为分配了:

 int a = 0; if(TrySomething(ref a)) {} 

但是,在这两种情况下( refout ),对TrySomething方法中的任何更改TrySomething持久保存到。

正如我已经说过的,对引用类型所做的更改将保留在您创建它们的方法之外,因为通过引用,您可以引用相同的内容。

但是,这没有做任何事情:

 public void Example(SomeReferenceType s) { s = null; } 

在这里,您只需将s的引用副本设置为null,该副本仅存在于方法的范围内。 它对传递给方法的任何内容都没有影响。

如果你想这样做,无论出于何种原因,请使用:

 public void Example1(ref SomeReferenceType s) { s = null; // Sets whatever you passed into the method to null } 

我认为这涵盖了outref所有用例。

典型的用例是一个需要返回多个东西的方法,因此它不能只使用返回值。 通常,返回值用于成功标志,而out参数在方法成功时设置值。

典型的例子是:

 public bool TryGet( string key, out string value ) 

如果返回true,则设置value。 否则,事实并非如此。 这使您可以编写如下代码:

 string value; if (!lookupDictionary.TryGet("some key", out value)) value = "default"; 

请注意,这不需要您在使用索引器之前调用Contains,这使得它更快更干净。 我还要补充一点,与非常相似的ref修饰符不同,如果out参数从未初始化,编译器不会抱怨。

Jon Skeet在本文中详细描述了传递参数的不同方法。 简而言之,out参数是未初始化传递给方法的参数。 然后需要该方法在任何可能的返回之前初始化参数。

通常,如果我们没有获得返回值,我们就无法获取函数内的变量。 但是使用关键字“out”我们可以通过函数更改它的值。