使用“out” C# 中的关键字

发布于 2024-12-09 05:34:38 字数 234 浏览 4 评论 0 原文

谁能告诉我“out”关键字作为参数的确切用法,以及它如何与从函数返回多个值相关联,如 将多个值返回给方法调用者帖子。

我对“out”变量与普通变量感到困惑。

Can anyone tell me the exact usage of the "out" keyword as a paramter, and how its connected to returning multiple values from a function, as in the Return multiple values to a method caller post.

I am confused with the "out" variable vs a normal variable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

柠檬 2024-12-16 05:34:38

这经常令人困惑,我认为 MSDN 文档实际上有点“只有在已知的情况下才清晰”。也就是说,它是正确的,但只有当你已经理解这个概念时它才有意义。

我是这样想的。

常规参数会复制参数。当你说:

static int M(int z) { z = z + 1; return z; }    
...
int x = 123;
int y = M(x);

这就像你说的那样:

int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;

引用或输出参数为现有变量创建别名。当您说

static void N(ref int q) { q = q + 1; }    
...
int x = 123;
N(x);

这与说:

int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;

qx 是引用同一个变量两个不同名称时 相同>。递增 q 也会递增 x,因为它们是相同的。上一个示例中的 zx两个不同的名称,它们引用两个不同的变量。增加 z 不会改变 x

总结:“out”和“ref”只是意味着“不要创建新变量;而是暂时为现有变量创建第二个名称”。

现在清楚了吗?

更新:我没有说“out”和“ref”之间的区别是什么。区别很简单。在“调用者”方面,“ref”必须是调用方法之前明确分配的变量。不一定要“出局”。在“被调用者”一侧,可以在写入“ref”之前读取“ref”,但必须在读取“out”之前写入“out”。此外,在控制正常离开方法之前必须写入“out”。

This is frequently confusing, and I think the MSDN documentation actually is a bit "clear only if already known". That is, it is correct, but it really only makes sense if you already understand the concept.

Here's how I think of it.

A regular parameter makes a copy of the value of the argument. When you say:

static int M(int z) { z = z + 1; return z; }    
...
int x = 123;
int y = M(x);

That is just like you said:

int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;

A ref or out parameter make an alias for an existing variable. When you say

static void N(ref int q) { q = q + 1; }    
...
int x = 123;
N(x);

That is the same as saying:

int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;

q and x are two different names that refer to the same variable. Incrementing q also increments x because they are the same. z and x in the previous example are two different names that refer to two different variables. Incrementing z does not change x.

Summing up: "out" and "ref" just mean "do not make a new variable; rather, temporarily make a second name for an existing variable".

Is that now clear?

UPDATE: I did not say what the difference between "out" and "ref" is. The difference is simple. On the "caller" side, a "ref" must be a definitely assigned variable before the method is called. An "out" need not be. On the "callee" side, a "ref" may be read before it is written to, but an "out" must be written to before it is read. Also, an "out" must be written to before control leaves the method normally.

〆一缕阳光ご 2024-12-16 05:34:38

MSDN 文档 已经做得很好了解释一下:

out 关键字导致参数通过引用传递。这是
与 ref 关键字类似,不同之处在于 ref 要求变量
在传递之前进行初始化。要使用输出参数,
方法定义和调用方法必须显式使用out
关键词。例如:

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}

MSDN documentation already does a great job explaining this:

The out keyword causes arguments to be passed by reference. This is
similar to the ref keyword, except that ref requires that the variable
be initialized before being passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword. For example:

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}
醉城メ夜风 2024-12-16 05:34:38

它经常用于“尝试”获取值的模式,例如:

int result;
if(Int32.TryParse("123", out result))
{
   Console.WriteLine(result + 1);
}

It's very frequently used in a pattern that "tries" to get a value, something like:

int result;
if(Int32.TryParse("123", out result))
{
   Console.WriteLine(result + 1);
}
魂归处 2024-12-16 05:34:38

在大多数语言(包括 C#)中,您可以通过两种方式传递值:
按值或按引用。

按值为该方法提供数据的副本,因此更改数据不会对原始数据产生任何影响。

通过引用实质上为该方法提供了数据的内存地址,因此如果该方法修改了数据,它就会更改原始数据。

“out”关键字是一种特殊的引用类型,因为您不需要在调用方法之前初始化变量。可以通过传入 null 来调用它,并且它必须由该方法设置。

您可以想到的另一种方式(从外部代码的角度)是:

val = read only
ref = 读/写
输出 = 只写

In most languages, C# included, you can pass values in 2 ways:
by value or by reference.

By value gives the method a copy of your data, so changing the data wont have any effect on the original data.

By reference essentially gives the method the memory address of your data, so if the method modifies the data, it changes the original data.

The "out" keyword is a special type of by reference, in that you do not need to initialise the variable before you call the method. It can be called with null being passed in and it MUST be set by the method.

Another way you can think of it (from the outside code's point of view) is:

val = read only
ref = read/write
out = write only

乄_柒ぐ汐 2024-12-16 05:34:38

当您想要执行以下操作时,应使用 out 关键字:
a) 允许您的函数修改调用代码堆栈中的特定变量并且
b) 强制在函数内设置此变量值

out keyword should be used when you want to:
a) Allow your function to modify specific variable from calling code stack AND
b) enforce setting this variable value inside your function

两人的回忆 2024-12-16 05:34:38

MSDN 始终是一个不错的起点

MSDN is always a good place to start

才能让你更想念 2024-12-16 05:34:38

http://msdn.microsoft.com/en-如果

您想返回预定义类型的多个值(例如intListDateTime),并且您不想仅为此目的创建一个新类。

http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx

out keyword is good if you want to return multiple values of pre-defined types (for example an int, a List<string> and a DateTime), and you don't want to create a new class just for this purpose.

紧拥背影 2024-12-16 05:34:38

好吧,

让我们看一下此类函数的常见模式 - TrySomething
假设您有一个函数可能会成功地为您提供一个值,也可能不会,但您不会为此使用异常,因为您不想要开销或者这是一个常见特征。
然后,如果方法成功,通常会返回 true ,否则返回 false 。但是你会把你的产出值放在哪里呢?

一种可能的答案是使用如下所示的 out 参数:

bool TrySomething(MyInputType input, out MyOutputType output)
{
   output = default(MyOutputType);
   /* ... Try getting the answer ... */
   if (!successful)
      return false;

   output = successfulOutput;
   return true;
}

备注:
或者您可能会考虑使用 Tuple 并且实际上 F# 将上面的模式解释为自己生成这样一个元组。

Ok,

let look at the usual pattern for this kind of function - the TrySomething.
Suppose you have a function that might succeed giving you an value or not but you don't won't to use an exception for this because you don't want the overhead or it's a common trait.
Then you normaly return true if the method suceeded and false if not. But where would you put your outputvalue to?

One possible answer is using an out parameter like this:

bool TrySomething(MyInputType input, out MyOutputType output)
{
   output = default(MyOutputType);
   /* ... Try getting the answer ... */
   if (!successful)
      return false;

   output = successfulOutput;
   return true;
}

Remark:
Or you might consider using a Tuple<bool,MyOutputType> and indeed F# interpretes the pattern above as resulting in such a tuple by itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文