我是否需要显式传递组合框作为函数中的引用,或者编译器会为我执行此操作
本文关键字:或者 引用 编译器 操作 执行 函数 组合 是否 | 更新日期: 2023-09-27 18:34:13
在C#.NET (WinForms(中,我有一个函数,它用查询的结果填充表单上的现有组合框:
FillComboBox("SELECT Value FROM Table", comboBox1);
public void FillComboBox(string query, ComboBox combobox)
{
cmd = new MySqlCommand(query, connection);
reader = cmd.ExecuteReader();
while (reader.Read())
{
combobox.Items.Add(reader[0]);
}
combobox.SelectedIndex = 0;
}
以上似乎工作正常,但是我也可以选择使用引用,如下所示:
FillComboBox("SELECT Value FROM Table", ref comboBox1);
public void FillComboBox(string query, ref ComboBox combobox)
{
cmd = new MySqlCommand(query, connection);
reader = cmd.ExecuteReader();
while (reader.Read())
{
combobox.Items.Add(reader[0]);
}
combobox.SelectedIndex = 0;
}
同样,这两个函数的工作方式相同 - 但是使用后一种函数是否更有效或更安全,将组合框作为参考传递?还是编译器在第一个函数中隐式执行此操作?
你的第二个例子,在工作时,是错误的,误导了你的意图。
引用变量(假设我们在此方法的调用代码中将其声明为 ComboBox cbx = new ComboBox();
(包含一个简单的值,该值表示存储组合框实例的内存地址。相同的变量 ( cbx
( 在堆上分配,并有自己的地址,用于存储new ComboBox()
调用返回的组合框实例的地址。
在第一个示例中,当您将 cbx
变量传递给 FillCombo 方法时,将在堆栈上创建该方法的本地新变量,并将 cbx
的值存储在那里(组合框实例的内存地址(。
因此,现在您可以自由更改组合框属性,调用方可以看到对组合框数据所做的更改。
当你使用 ref 关键字时,事情会发生变化。在第二个示例中,FillCombo 方法仍然创建一个名为 combobox
的局部变量,但此局部变量接收 cbx
的地址,而不是其值。此处的目的是创建一个 ComboBox 的新实例,调用类似 combobox = new ComboBox();
的内容(不同实例的不同地址(,并使用传递变量的地址值让传递的变量"指向"新实例。
从性能的角度来看,我认为没有可衡量的差异(如果有的话(,但 ref 关键字的存在只是误导。
好的参考文章是:
C#概念:值类型与引用类型 来自 Joseph Albahari
来自 Jon Skeet 的 C# 中的参数传递
在第一个代码示例中,传递combobox1
引用的副本。所以你可以访问comboBox1
的属性,因为combobox
参数引用与comboBox1
相同的对象。如果你尝试创建新对象:combobox = new ComboBox()
- 你不会更改comboBox1
,因为combobox
是它的副本。在第二个代码示例中,传递comboBox1
引用(而不是副本(。您还可以像第一个代码示例中一样访问comboBox1
属性,但现在您可以更改comboBox1
,因为您传递了直接引用:combobox = new ComboBox()
将与comboBox1 = new ComboBox()
相同。