【问题标题】:Difference between instantiating then assigning vs declaring then assigning?实例化然后分配与声明和分配之间的区别?
【发布时间】:2014-02-26 07:49:05
【问题描述】:

我的一个朋友问我这个问题。虽然我回答了它,但我不是很相信自己。我所寻求的只是满足或纠正。代码sn-p如下:

class Program
{
    static void Main(string[] args)
    {
        DataTable dt1 = new DataTable("Customer");
        dt1.Columns.Add("ID", typeof(int));
        //and some more columns
        dt1.Rows.Add(1);

        *****//what is the difference between doing
        DataTable dt2 = dt1;
        //vs.
        DataTable dt3 = new DataTable();
        dt3 = dt1;*****
    }
}

据我目前所知,使用new 关键字会在堆上创建对象,并在堆栈上创建一个指针变量,而堆栈仅用于简单的数据类型,如 int、double 等和指针。

根据我的理解,我解释说,dt2 将创建在能够指向堆中任何DataTable 类型的堆栈上,并且当我们将dt1 分配给dt2 时,它将指向dt1指向同一个数据表。在 dt3 的情况下,在堆上创建了一个新的数据表对象,dt3 将指向它,但是当我们执行dt3 = dt1 时,它开始指向dt1 指向的DataTable 而不是那个创建的。

我不太相信我给出了正确的解释,尤其是。关于dt3的部分。所以我希望社区要么纠正我,要么向我保证我是对的。

【问题讨论】:

  • 是的,没错。第二种形式毫无意义。您创建了一个新的DataTable,但随后立即通过将dt3 分配给dt1 来丢弃您对它的唯一引用,因此新创建的DataTable 只是被安排进行垃圾收集,而无需执行任何操作。

标签: c# .net object heap-memory stack-memory


【解决方案1】:

总的来说,你是对的。在DataTable dt3 = new DataTable(); 行中,您创建一个新的DataTable 对象,dt3 引用指向它。然后,在dt3 = dt1 之后,您忘记了这个对象。 dt3 指向的是之前创建的对象,即:new DataTable("Customer")。您“忘记”的对象可能会被垃圾回收,因为没有对它的引用。

【讨论】:

  • 甜蜜!基本上那么没有必要做第二种方法。曾经!不是吗?另外,如果是这种情况,我认为我不会错说“new”关键字可以按字面意思用于创建新对象,如果需要一个变量来指向现有对象,则应该简单地声明它。跨度>
  • @HakuKalay 好吧,我可以想象,在一些非常罕见的情况下,您可能希望实例化一个对象只是为了调用它的构造函数,但总的来说,在这个特定的例子中,是的,没有意义这样做。
【解决方案2】:

你基本上是正确的。每个变量dt1dt2dt3 都是DataTable 对象的引用。当在类类型的变量之间使用赋值运算符时,会发生称为引用赋值的事情。这意味着当您键入 dt3 = dt1 时,您正在更改 dt3 以引用完全不同的 DataTable 对象 - 在这种情况下,dt1 所引用的 DataTable 对象相同。

请务必注意,这是类的引用语义的一部分。您正确地注意到“简单的数据类型,如 int、double 等”是在堆栈上分配的。事实上,所有结构都是如此。在c#中,类和结构的根本区别在于类有引用语义,而结构有值语义

这意味着如果您声明了struct DataTable 而不是class DataTable,那么堆栈上将有三个DataTable 对象,而dt3 = dt1 语句将复制@987654336 中的DataTable 对象@按值转化为dt3

intbool 这样的简单类型实际上是结构体,因此存在于堆栈中并按值复制/传递。

当然,如果没有指向 Eric Lippert 的文章 "The Stack Is An Implementation Detail" 的链接,任何关于值类型与引用类型的讨论都是不完整的。我在这个答案中谈到了一些关于“生活在堆栈上”的结构,但这只是为了说明这一点。尝试摆脱将类视为“堆类型”和将结构视为“堆栈类型”的习惯,开始从“引用类型”和“值类型”的角度来思考它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    • 2011-06-15
    • 2015-11-24
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多