这个“if”分支中的“out”关键字的目的是啥(用于 WebMatrix 的 OAuth“Starter Site”模板)? [复制]

Posted

技术标签:

【中文标题】这个“if”分支中的“out”关键字的目的是啥(用于 WebMatrix 的 OAuth“Starter Site”模板)? [复制]【英文标题】:What is the purpose of the "out" keyword in this "if" branch (used in OAuth "Starter Site" template for WebMatrix)? [duplicate]这个“if”分支中的“out”关键字的目的是什么(用于 WebMatrix 的 OAuth“Starter Site”模板)? [复制] 【发布时间】:2013-03-23 01:10:46 【问题描述】:

我的问题主要集中在一件事上。在这个示例分支中,out 关键字究竟做了什么?

if (!OAuthWebSecurity.TryDeserializeProviderUserId(loginData, out provider, out providerUserId)) 
            Response.Redirect("~/Account/Manage");
            return;
        

我看过这里:http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx

但事实是,我不知道“通过引用传递的参数”是什么意思,就像我不知道“ref”关键字是/做什么一样。

很抱歉,这方面太新了,但我似乎无法理解它的作用。

这个 sn-p 来自 WebMatrix2 的“Starter Site”模板中的 RegisterService.cshtml 文件。

【问题讨论】:

我意识到这个问题与 SO 上提出的其他几个问题非常接近,但我觉得这些问题中的两个 OP 都比我对它的理解要多一些,我不能'没有真正理解'为什么'有人会使用 out/ref 您可能想阅读 Jon Skeet 的 Parameter passing in C# 【参考方案1】:

表示这些参数是过程的输出。这是从过程中“返回”多个值而不创建类来存储结果的一种方法。在这种情况下,有三个“结果”(两个参数加上真正的布尔返回值)。

如果 C# 允许多个返回值,则相当于:

bool canDeserialize;
canDeserialize, provider, providerUserId = OAuthWebSecurity.TryDeserializeProviderUserId(loginData); 
if (!canDeserialize)
            Response.Redirect("~/Account/Manage");
            return;
        

另一个在 C# 中有效的选项是创建一个类来存储结果:

public class ProviderParseResults

   public string Provider get; set;
   public string ProviderUserId get; set;

然后这样使用:

ProviderParseResults results = OAuthWebSecurity.TryDeserializeProviderUserId(loginData); 
if (results == null)
            Response.Redirect("~/Account/Manage");
            return;
        

string provider = results.Provider;
string providerUserId = results.ProviderUserId;

【讨论】:

另外,out 关键字指定变量必须在离开方法体之前赋值。而ref 并不强制要求此要求。 输出什么程序?方法调用本身?所以不是传入变量,而是在方法执行后将它们取出?我不认为我说得对吗? 从技术上讲,您仍然可以将out 值传递给方法本身; out 只要求该方法为它们分配一个值。此外,ref 可以很容易地返回值,不同之处在于它不需要在方法中分配它们。 @VoidKing 将out 参数视为方法的返回值。使用out 是在说“好的,这里有一些变量。当我叫你方法先生时,你必须在其中存储一些东西 好的,所以在使用它的 2 个输出变量调用此方法后(我可以这样称呼它们吗?),我可以操纵这些变量,就像我可以将任何其他变量传递给方法一样,只有方法将自操作变量作为输出返回到调用它的原始代码/页面/方法?稍后,在同一个 cshtml 页面中,我可以引用 provider 和 providerUserId 的新值?【参考方案2】:

既然你不知道通过引用传递参数意味着什么我就从这个开始。

通常,在调用函数时,您会按值传递参数。这意味着您将值作为参数发送,而不是变量。

所以如果我打电话:

a = 10;
some_func(a);

这与调用基本相同:

some_func(10);

因为您实际上发送的是 a 中包含的值,而不是实际的变量 a

但是,如果您希望您的函数真正改变 a 中的值怎么办?在这种情况下,您需要将函数的参数作为引用发送,以便将变量本身提供给函数。这是一个例子:

void sum( int a, int b, ref int c )

    c = a + b;

正如您在上面的函数中看到的,该函数按值接收 a 和 b,因为它不打算更改它们。但是 c 是通过引用传递的,因为我们打算把函数的结果放在这个变量中。

现在来看看 refout 之间的区别。

如果你尝试调用上面的函数,你可能会收到一个编译错误,告诉你正在向函数发送一个未初始化的变量。

但这不应该是一个问题(在这种情况下),因为我引用的变量实际上是一个输出,所以我并不关心之前存储在其中的值是什么。

因此,我可以使用 out 关键字来代替使用 ref 关键字声明这个变量,这样编译器就知道这个变量只是一个输出,所以它不需要检查它是否已经初始化

【讨论】:

非常棒的答案! (并不是说 D Stanley 不是)所以,如果我使用 ref,我将不得不声明它,从而建立一些值,一个我可以在方法中引用和操作的值,但没有我不必声明任何东西,因为我不会引用一个值,只是设置它然后将其传递出去? 在这两种情况下都需要声明要发送的变量(通过引用)。不同之处在于,如果没有 out 关键字,变量可以是未初始化的,这意味着在将其传递给函数之前,您无需关心其中的初始值

以上是关于这个“if”分支中的“out”关键字的目的是啥(用于 WebMatrix 的 OAuth“Starter Site”模板)? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

使用 continue 关键字的目的是啥

java中的关键字transient是啥意思

C语言的分支语句有哪几种?C语言分支结构的基本形式是啥,区别是啥?

c语言的37个关键字都是啥

这个场景中默认关键字的目的是啥[重复]

JavaScript中的分支结构