我是否需要显式传递组合框作为函数中的引用,或者编译器会为我执行此操作

本文关键字:或者 引用 编译器 操作 执行 函数 组合 是否 | 更新日期: 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()相同。