为啥 ref 参数类型与常规类型不同?
Posted
技术标签:
【中文标题】为啥 ref 参数类型与常规类型不同?【英文标题】:Why is a ref parameter type different to the regular type?为什么 ref 参数类型与常规类型不同? 【发布时间】:2012-02-12 02:58:25 【问题描述】:我了解如何在两种不同类型之间进行切换,但我的问题是;为什么这种差异在类型级别?
我原以为它是ParamterInfo
对象的属性,而不是单独的特殊类型。
假设它在反射中作为一个单独的类型呈现,因为它在内部就是这样,将它作为一个单独的类型有什么语言好处(我猜是更容易的方法重载解析或其他东西)?
在类似的说明中,为什么ref
是一个独特的类型而out
不是(我想不出ref
是一个单独的类型的原因,这不适用于out
)?
【问题讨论】:
【参考方案1】:ref
参数具有不同的类型,因为ref
类型在参数以外的其他上下文中也是允许和有用的。 C# 不允许,但其他语言(至少 C++/CLI)确实支持,例如,引用类型的局部变量。这样的事情对ref
有意义,但对out
没有意义。
假装C#允许,你可以写(IL支持):
int x = 3;
ref int y = x;
y = 4;
if (x == 4)
MessageBox.Show("x is 4");
这不是一个有用的例子,但在ref
参数有用的相同情况下,使用带有@987654327的辅助类或结构也很有用@字段。
【讨论】:
啊,有道理。一个例子会有所帮助。我看不出你会如何使用 ref local。 更新了一个毫无用处的例子:) 啊,我明白了,但仍然不太确定实际的应用程序。猜猜你可能有 y 指几个变量或某事之一(或数组中的元素?)。 另一件事是,ref 对互操作很有用,因为 ref 在非托管代码中传递时将表现为指针。另一方面,out 不能与互操作一起使用。 一个 ref return type 函数的示例,即使您无法在 C# 中自己定义它,C# 也会使用它是数组上的 Address 函数,它允许您使用多维数组元素的地址(为了传递给 ref 参数)。【参考方案2】:public static int SomeMethod(string local, ref string strParam)
local = SomeStaticlyHeldString;
strParam = SomeStaticlyHeldString;
int localInt = local.Length;
return strParam.Length;
对local
的赋值意味着local
标记的内存位置现在指向SomeStaticlyHeldString
指向的同一个对象。
对strParam
的赋值意味着参数传递给使用ref
标签的方法的内存位置现在指向SomeStaticlyHeldString
指向的同一个对象。
获取local.Length
查询local
指向的对象。获取strParam.Length
查询strParam
所指向的变量,所指向的对象。
两者的行为确实非常不同,不仅仅是在定义参数或本地时,而是在每次使用它们时。差异在很大程度上是隐藏的,这使得它们更加不同,因为对它们的每次操作在效果上都不同。
如果我们有一个只有局部变量、某种非局部堆上的对象以及指向这两者的指针的低级语言,那么local
的类型将是string*
和strParam
输入string**
。这将是我们如何在 C 中进行类似的操作,以及我们如何在 C++ 中这样做,尽管它也有引用类型(尽管在 C++ 中,类型是引用类型更清楚地是其类型定义的一部分,并且它们有进一步的用途和改进)。 C# 在其语法中几乎对我们隐藏了所有这些内容。任何隐藏细节的好处总是值得商榷,但在这种情况下,隐藏任何有用的东西并没有太多好处,因此很难批评它。
【讨论】:
接受这个作为 IMO 可以更好地回答我的问题。谢谢。 :)以上是关于为啥 ref 参数类型与常规类型不同?的主要内容,如果未能解决你的问题,请参考以下文章
Blazor - SetParameters - 为啥字符串参数绑定的行为与复杂类型不同