为什么数据集通过引用传递而没有显式传递或ref参数
本文关键字:参数 ref 数据集 引用 为什么 | 更新日期: 2023-09-27 18:02:32
我看不懂这段代码,这里对DataSet对象和字符串变量的实现相同,但输出不同。我可以看到字符串变量输出背后的逻辑,但对于数据集,我不明白为什么!
class Program
{
static void Main(string[] args)
{
DataSet ds = new DataSet();
FillDS(ds);
PrintDS(ds);
string name = "old";
AssignString(name);
PrintString(name);
}
private static void AssignString(string name)
{
name = "new name";
}
private static void PrintString(string name)
{
Console.WriteLine(name);
}
private static void FillDS(DataSet ds)
{
ds.Tables.Add(new DataTable("tbl1"));
ds.Tables.Add(new DataTable("tbl2"));
}
private static void PrintDS(DataSet ds)
{
foreach (DataTable item in ds.Tables)
{
Console.WriteLine(item.TableName);
}
}
}
//Output:
//tbl1
//tbl2
//old
字符串是不可变的,加上你没有修改字符串参数(不是你可以),而是你分配一个新的引用给你的参数。原来的仍在原地。
对于DataSet
,您正在修改其内容,并且由于它是一个可变引用类型,因此您可以在调用方中看到更改。
在Main
DataSet ds = new DataSet();
ds.Tables.Add(new DataTable("tbl3"));
FillDS(ds);
,然后在FillDS
中给DataSet
分配一个新的引用,如:
private static void FillDS(DataSet ds)
{
ds = new DataSet(); //Here
ds.Tables.Add(new DataTable("tbl1"));
ds.Tables.Add(new DataTable("tbl2"));
}
你会看到你的DataSet
仍然保持旧的值,并且在调用FillDS
string
和DataSet
都是引用类型。所以在这两种情况下都传递引用。
在AssignString
方法中,您不更改传递的string
实例,但将新实例 ("new name"
)分配给变量name
。name
变量实际上是一个参数这一事实并不重要(尽管重新分配参数被认为是一种不好的做法)。
在FillDS
中,不是重新分配一个新实例,而是通过ds.Tables....
访问和操作传递的实例的属性。
因为DataSet
和string
都是引用类型,并且在引用类型中,它总是传递对象在托管堆上的内存地址。