Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基本.NET-如何引用';存储/解析';_C#_Asp.net_Pointers_Reference - Fatal编程技术网

C# 基本.NET-如何引用';存储/解析';

C# 基本.NET-如何引用';存储/解析';,c#,asp.net,pointers,reference,C#,Asp.net,Pointers,Reference,请注意以下代码: Control foo = null; Control bar = null; int i = 0; protected void Page_Load(object sender, EventArgs e) { test(); test(); Page.Controls.Add(foo); } void test() { i++; bar = new Control(); bar.Controls.Add(new Litera

请注意以下代码:

Control foo = null;
Control bar = null;
int i = 0;

protected void Page_Load(object sender, EventArgs e)
{
    test();
    test();
    Page.Controls.Add(foo);
}

void test()
{
    i++;
    bar = new Control();
    bar.Controls.Add(new LiteralControl(i.ToString()));
    if (foo == null)
    {
        foo = new Control();
        foo.Controls.Add(bar);
    }
}
在尝试上面的代码时,我惊讶地看到打印的结果是“1”(而不是“2”)

我假设这是因为当我向
foo
添加控件
bar
时,
foo.Controls.Add()
解析引用
bar
,而不仅仅是存储引用本身

1) 有人能证实这一点吗,或者可能详细说明一下


2) 我有一种感觉,如果我被允许做
foo.Controls.Add(参考条)它将显示“2”,但显然该语法是非法的。在不进行重大重构的情况下,是否可能出现这种情况

比这简单多了。foo是类作用域的对象。第二次运行test()时,它不会发生任何变化,因为它不是null。所以它只是返回您从第一个test()添加到它的内容,这是一个字符串值为“1”的新LiteralControl。“1”只是文本,它不是对i的引用

顺便说一下,
foo.Controls.Add(参考条)
实际上就是这样。控件(对象)始终通过引用添加,这是其存在的本质。要将对象的实际值传递给某个对象,基本上必须先复制该对象。但你还是会传递一个副本的引用

如果您更改了
条的内容
,它确实会更改输出

我认为您在这里感到困惑的是,您在第二次运行test()时没有处理相同的
bar
,因为每次都会创建一个新的

(编辑)

顺便说一下,如果您只更改了这一行:

 bar = new Control();

它的行为将如预期的那样,因为第二次通过您不会像现在这样用一个新的引用替换掉原来的“bar”引用。(Sorta…实际上它会说“12”,因为你会在其中添加两个LiteralControl)。

调用

foo.Controls.Add(bar);
使用
条的当前值
。这是指包含文本为“1”的
文字控件的
控件

现在稍后,您将更改
bar
的值以引用一个完全不同的控件。。。但是这与
foo.Controls
中已经存储的内容没有任何区别。即使您可以通过引用将
bar
传递到
Add
方法中,实际上也不会有任何区别

我强烈建议,如果您不确定引用、参数等在.NET中如何工作,请使用控制台应用程序检查您的理解。它们更易于使用、调试等

您可能还想阅读我关于和的文章。

第一次运行
test()
时,将创建一个新控件(我称之为
Control1
),并在
栏中存储对它的引用。因为
foo
为空,所以它被设置为一个新控件,其中添加了条中的引用

所以现在
Control1
现在被
bar
和foo.Controls集合引用

第二次运行
test()
foo
现在不为空,因此不进行修改


所以现在
bar
是对
Control2
的引用,但是
foo。Controls
仍然包含对
Control1
的引用。foo只创建一次(在第一次调用test时),然后添加标签为1的LiteralControl


在第二次调用test()时,旧引用(标签1)将替换为新控件。但是,添加到foo中的条仍然存在并且没有受到影响。

Jon Skeet的回答是好的(当然),但我只想强调一点:

引用类型的变量(如bar和foo)不包含对象,它们包含对对象的引用。

因此,第一次通过test()方法,bar包含对控件的引用,该控件中有一个1。这个引用被添加到foo中

第二次使用test()方法时,bar包含对另一个控件的引用,该控件中有一个2。而该引用不会添加到foo中

为什么第二次是不同的参考?因为在test()的开头,你说
bar=newcontrol(),用于在条形图中存储对新控件的引用。从那时起,bar与它之前提到的控件无关,尽管对该控件的引用仍然存在于foo的Controls集合中

如果要更改代码,使其符合预期,可以执行以下操作:

Control foo = null;
Control bar = new Control();
int i = 0;

protected void Page_Load(object sender, EventArgs e)
{
    test();
    test();
    Page.Controls.Add(foo);
}

void test()
{
    i++;
    bar.Controls.Clear()
    bar.Controls.Add(new LiteralControl(i.ToString()));
    if (foo == null)
    {
        foo = new Control();
        foo.Controls.Add(bar);
    }
}
在这种情况下,我们一次只在bar中存储一个新引用,所以当所有操作都完成时,它应该仍然与我们添加到foo中的引用相匹配

Control foo = null;
Control bar = new Control();
int i = 0;

protected void Page_Load(object sender, EventArgs e)
{
    test();
    test();
    Page.Controls.Add(foo);
}

void test()
{
    i++;
    bar.Controls.Clear()
    bar.Controls.Add(new LiteralControl(i.ToString()));
    if (foo == null)
    {
        foo = new Control();
        foo.Controls.Add(bar);
    }
}