为什么 ref 参数类型与常规类型不同?

发布于 2024-12-27 15:51:32 字数 430 浏览 2 评论 0原文

我了解如何在两种不同类型之间切换,但我的问题是;为什么类型级别存在这种差异

我本以为它是 ParamterInfo 的属性 对象,而不是单独的特殊类型。

假设它在反射中呈现为单独的类型,因为它的内部就是这样,那么将其作为单独的类型有什么语言好处(我猜更容易的方法重载解析或其他什么)?

同样,为什么 ref 会产生不同的类型,而 out 却不会(我想不出 ref 是一个不同的类型的原因)单独的类型,不适用于 out)?

I understand how to go between the 2 different types but my question is; why is this difference at the type level?

I would have thought it would be a property of the ParamterInfo object, not separate special type.

Assuming it's presented as a separate type in reflection because that is how it is internally, what language benefits are there to having this as a separate type (I'm guessing easier method overload resolution or something)?

On a similar note, why does ref make a distinct type but out doesn't (I can't think of reasons for ref being a separate type, that don't apply to out)?

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

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

发布评论

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

评论(2

遗忘曾经 2025-01-03 15:51:32

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 参数有用的相同情况下,使用带有 ref 字段的辅助类或结构也很有用。

ref parameters have distinct types because ref types are also allowed and useful in other contexts than parameters. C# doesn't allow it, but other languages (at least C++/CLI) do support, for example, local variables of reference type. Such a thing makes sense for ref, but not for out.

Pretending C# allows it, you could write (it's supported by IL):

int x = 3;
ref int y = x;
y = 4;
if (x == 4)
    MessageBox.Show("x is 4");

This isn't an example of when it's useful, but in the same situations where ref parameters are useful, it can also be useful to use a helper class or struct with a ref field.

剑心龙吟 2025-01-03 15:51:32
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*< 类型/code> 和 strParam 类型为 string**。这就是我们在 C 中执行类似操作的方式,以及我们如何在 C++ 中执行此操作,尽管它也有引用类型(尽管在 C++ 中,类型是引用类型更清楚地是其类型定义的一部分,并且它们有进一步的用途和改进)。 C# 在其语法中向我们隐藏了几乎所有这些内容。隐藏任何细节的好处总是有争议的,但在这种情况下,隐藏任何有用的东西并没有太多,所以人们很难批评它。

public static int SomeMethod(string local, ref string strParam)
{
  local = SomeStaticlyHeldString;
  strParam = SomeStaticlyHeldString;
  int localInt = local.Length;
  return strParam.Length;
}

The assignment to local means that the place in memory that local labels now points to the same object that SomeStaticlyHeldString was pointing to.

The assignment to strParam means that the place in memory that the argument passed to the method using ref labels, now points to the same object that SomeStaticlyHeldString was pointing to.

Obtaining local.Length queries the object that local points to. Obtaining strParam.Length queries the object that the variable that strParam points to, points to.

The two are really behaving very differently, not just at the point the parameter or local is defined, but with every use of them. That the difference is largely hidden makes them all the more different, as every operation upon them differs in effect.

If we had a lower level language that had nothing but local variables, objects on some sort of non-local heap, and pointers to both of those, then local would be of type string* and strParam of type string**. This would be how we would do a similar sort of operation in C, and how we could do so in C++ though it also has reference types (though with C++ that a type is a reference type is more clearly part of its type definition, and they have further uses and refinements). C# hides almost all of this from us in its syntax. It's always debatable how beneficial any hiding of details is, but in this case there isn't much in the way of anything useful being hidden, so it's one that one would be hard-pressed to criticise.

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