通过引用传递此内容(参考此)

本文关键字:参考 引用 | 更新日期: 2023-09-27 18:32:02

请考虑以下代码片段(在Windows表单应用程序中编写):

public partial class Form1
{
    ....
    public void Caller()
    {
        Form1 myRef = this;
        Change(ref this)    //--> won't compile because *this* is read-only
        Change(ref myRef);  //--> compiles but doesn't work.
    }
    ....
    public void Change(ref Form1 theRef)
    {
        theRef = new Form1();
        theRef.Text = "I am a new form";
    }
}

不允许通过引用传递this。这没关系,也很明智。但是,为什么如上所述间接传递this不起作用呢?据我所知,如果参数是通过引用传递的,则被调用方法中的任何赋值都会反映到调用者方法中。为什么它在这里不起作用?

更新以明确问题

1- 我没有努力完成任何特别的事情。我只是想测试ref.

2-我误解ref的原因是我完全忘记了Form1 myRef = this实际上将底层Form1对象的地址复制到myRef;所以myRef变量与this无关,除了它们都指向同一个对象。

通过引用传递此内容(参考此)

它按预期工作。问题是这与您所期望的不一样。

Form1 myRef = this;
var b1 = object.ReferenceEquals(myRef, this); // true
Change(ref myRef);
var b2 = object.ReferenceEquals(myRef, this); // false

因此,myRef的价值会发生变化。应该预料到更改不会传播到this;赋值后myRefthis是完全独立的变量。C# 没有"ref 变量",因此它不可能是任何其他方式(即使有,也永远不会允许以这种方式重新分配this)。

使用 myRef 确实有效,在方法调用之后,它实际上是对新 Form 实例的引用。它还将更改 Text 属性,但您不会看到任何内容,因为您没有显示新的 Form 实例。它与原始表单(this不同,因此该表单不会以任何方式更改。

如果要更改窗体的属性,可以这样做:

public void Change(Form1 theRef)
{
    theRef.Text = "I am a new form";
}

可以这样称呼:

Change(this);

但是您不能像这样创建一个"新表单"来替换现有表单。也许您应该考虑使用某种Reset()功能,根据需要清除表单。

如果您确实需要替换当前表单,那么您将需要某种可以管理原始表单的"父级"。

因为您无法为this赋值。

实际上它有效。我假设您希望您当前的形式发生变化,但这不会像这样工作。代码的作用是更改传递的引用的内容。它不会破坏/替换您当前的表单。

你需要做的是这样的

  • 创建(新)表单并打开它 (.显示或 。显示对话框)
  • 销毁当前表单 (.关闭)

在引用类型中,this是只读的,因此无法解决此问题。

您的第二次调用确实有效,但它会更改myRef变量以引用新形式。 this仍然引用原始形式,因为无论如何您都无法更改它。

这个答案只是对上面评论的更完整的回应,以澄清thisC#/.NET 中并不是只读的。

在值类型中,您可以为this赋值,但仍然无法通过引用传递this,因此您的代码仍然不起作用。

但是,下面是一个将新值分配给 this 的 LINQPad 示例,该值在值类型中"有效"。

void Main()
{
    Test t = new Test(17);
    t.Dump();
    t.StrangeMutation();
    t.Dump();
}
public struct Test
{
    public readonly int Value;
    public Test(int value)
    {
        Value = value;
    }
    public void StrangeMutation()
    {
        this = new Test(42);
    }
}

请注意,Value字段是只读的,因此该字段似乎无法更改其值,但是上述程序的输出是,首先该字段的值为 17,下次我们检查它时,它的值为 42。

但是,这仅适用于值类型。它不适用于引用类型,您也不能通过引用传递。