为什么DataSet是通过引用传递而没有显式传递或引用参数?

msh*_*hwf 0 c#

我无法理解这段代码,这里对DataSet对象和字符串变量实现相同,但输出不同,.I可以看到字符串变量输出背后的逻辑,但是对于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
Run Code Online (Sandbox Code Playgroud)

Hab*_*bib 6

字符串是不可变的,而且你没有修改字符串参数(不是你可以),而是你要为你的参数分配一个新的引用.原件仍然存在.

使用DataSet,您正在修改其内容,因为它是一个可变引用类型,您可以看到调用者的更改.

请尝试以下内容 Main

    DataSet ds = new DataSet();
    ds.Tables.Add(new DataTable("tbl3"));
    FillDS(ds);
Run Code Online (Sandbox Code Playgroud)

然后FillDS为你的DataSet喜欢分配一个新的参考:

private static void FillDS(DataSet ds)
{
    ds = new DataSet(); //Here 
    ds.Tables.Add(new DataTable("tbl1"));
    ds.Tables.Add(new DataTable("tbl2"));
}
Run Code Online (Sandbox Code Playgroud)

您将看到DataSet仍然保留旧值,并且在调用后没有任何内容被修改FillDS


Ren*_*ogt 6

这两个stringDataSet引用类型.所以在这两种情况下都会传递引用.

在该AssignString方法中,您不会更改string传递的实例,而是为该"new name"变量分配新的实例()name.该事实name变量实际上是一个参数没关系(虽然它被认为是一个不好的做法,重新分配参数).

FillDS重新分配新实例,但通过访问和操作传递的实例的属性ds.Tables.....