在类

时间:2018-05-07 05:53:24

标签: c#

最近,我在互联网上发现了一个问这个问题的帖子,我试图找出但不确定。

我猜这个问题与拳击和拆箱有关:

public readonly object counter = new Counter();

此行将Counter装入堆,而counter指向它。

((Counter)riddle.counter) 

此行从堆中取消装箱。

每次从堆中取消装箱的数据都与原点相同。因此,A行不会影响B行,因为它们都是从堆中检索的,并且是Counter的两个不同实例。

是吗?抱歉我的英语不好。

public void WantToKnow()
{
    var riddle = new Riddle();
    ((Counter)riddle.counter).Increment();  // Line A

    Console.WriteLine(((Counter)riddle.counter).Count); // Line B
    // Why the output is 0?///////////////////
}

struct Counter
{
    private int x;
    public void Increment() { this.x++; }
    public int Count { get { return this.x; } }
}

class Riddle
{
    public readonly object counter = new Counter();
}

2 个答案:

答案 0 :(得分:1)

首先,这是我几乎在所有情况下都试图避免可变结构的一个很好的例子。虽然你通常可以预测如果你给予足够的重视会发生什么,但很容易错过一个副本,这会让一切都搞砸。如果你保持所有结构不变,生活就会更简单。

对于您的问题:是的,您正在拆箱,这会创建计数器的副本。更改该副本不会影响其他任何内容。 (没有复制就有IL到unbox,但C#从不使用它。)

可以通过让你的计数器实现一个Increment操作的接口来实现这项功能。此时,您可以转换为界面而不是值类型,这意味着它不会取消装箱。然后,您的Increment操作会修改框内的值,这意味着您可以再次获取该值。这是一个完整的例子:

using System;

class Program
{
    static void Main()
    {
        var riddle = new Riddle();
        ((ICounter)riddle.counter).Increment();

        Console.WriteLine(((Counter)riddle.counter).Count); // Line B
    }
}

interface ICounter
{
    void Increment();
}

struct Counter : ICounter
{
    private int x;
    public void Increment() { this.x++; }
    public int Count { get { return this.x; } }
}

class Riddle
{
    public readonly object counter = new Counter();
}

答案 1 :(得分:0)

因为struct是值类型 - 你可以使用“class counter”struct struct Counter“ 或使用以下解决方案
原因 :((计数器)riddle.counter).Count被视为struct的另一个副本而不是ref类型。所以它显示初始值0

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {

         var riddle = new Riddle();
             Console.WriteLine(((Counter)riddle.counter).Increment());
            ///////////////////////////////////////////
            Console.WriteLine(((Counter)riddle.counter).Count);
            // Why the output is 0?///////////////////
    }


}
struct Counter
        {
            private int x;

            //Change is here    
            public int Increment() { this.x++; return this.x; }
            public int Count { get { return this.x; } }
        }

        class Riddle
        {
            public readonly object counter = new Counter();
        }