这个“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 是通过引用传递的,因为我们打算把函数的结果放在这个变量中。
现在来看看 ref 和 out 之间的区别。
如果你尝试调用上面的函数,你可能会收到一个编译错误,告诉你正在向函数发送一个未初始化的变量。
但这不应该是一个问题(在这种情况下),因为我引用的变量实际上是一个输出,所以我并不关心之前存储在其中的值是什么。
因此,我可以使用 out 关键字来代替使用 ref 关键字声明这个变量,这样编译器就知道这个变量只是一个输出,所以它不需要检查它是否已经初始化
【讨论】:
非常棒的答案! (并不是说 D Stanley 不是)所以,如果我使用 ref,我将不得不声明它,从而建立一些值,一个我可以在方法中引用和操作的值,但没有我不必声明任何东西,因为我不会引用一个值,只是设置它然后将其传递出去? 在这两种情况下都需要声明要发送的变量(通过引用)。不同之处在于,如果没有 out 关键字,变量可以是未初始化的,这意味着在将其传递给函数之前,您无需关心其中的初始值以上是关于这个“if”分支中的“out”关键字的目的是啥(用于 WebMatrix 的 OAuth“Starter Site”模板)? [复制]的主要内容,如果未能解决你的问题,请参考以下文章