再次在界面中构造;为什么我可以像上课一样使用它?

时间:2019-07-13 11:50:51

标签: c# struct interface

为什么我可以使用((I)o).Set(5,5); 输出类似5,5的类之类的结构 是的,o是对象,但我不能((I)s).Set(4,4); //输出1,1 为什么((I)s).Set(4,4)的输出不变,而((Io))。Set(5,5)的输出却改变了?

我知道我的代码将s隐式转换为I(引文)。 问题也在代码注释中。

    interface I
    {
        void Set(int x, int y);
    }

    public struct S : I

    {
        int x, y;
        public S(int x, int y)
        {
            this.x = x;
            this.y = y;

        }
        public void Set(int x, int y)
        {
            this.x = x;
            this.y = y;

        }
        public override string ToString()
        {
            return String.Format("{0} {1}", x, y);
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                S s = new S(1, 1);
                Console.WriteLine(s);

                object o = s;

                ((I)o).Set(5, 5);
                Console.WriteLine(o); // Why this works like class and outputs 5,5 instead of 1,1? 
             ((I)s).Set(4, 4); // why i can`t change reference.  why it outputs 1,1 instead of 4,4
            }

            catch { }

        }
    }

2 个答案:

答案 0 :(得分:1)

当您进行强制转换(I)s时,将通过复制S创建s的另一个实例,并将其放置为堆,因为接口是引用类型。因此,此时您有两个S的实例:一个在堆栈中,另一个在堆中。

因此,当您执行((I)s).Set(4, 4);时,您将更改堆中的第二个。

最后Console.WriteLine(s);打印出第一个,即堆栈中的那个。

要获得正确的输出,您必须执行以下操作:

var i = (I)s;
i.Set(4, 4);
Console.WriteLine(i);

答案 1 :(得分:1)

因为

((I)s).Set(4, 4)

被称为,发生了什么

1)((I)s)将结构转换为对象(装箱)

2)Set方法将更改应用于该对象(后来由于没有引用指向该对象而被垃圾收集器丢弃),但结构保持不变

((I)o)是否将一种引用类型转换为另一种引用类型,但对象保持不变。

从这里进行解释: https://blogs.msdn.microsoft.com/abhinaba/2005/10/05/c-structs-and-interface/