首页 > 解决方案 > 再次在接口中构造;为什么我可以像上课一样使用它?

问题描述

为什么我可以使用 struct like class by ((I)o).Set(5, 5); 它输出 5,5 是的,o 是对象,但我不能((I)s).Set(4, 4); // 输出 1, 1 为什么 ((I)s).Set(4, 4) 输出值不变但 ((I)o).Set(5, 5) 输出改变?

我知道我的代码隐含地将(引文)转换为 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 { }

        }
    }

标签: c#structinterface

解决方案


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

因此,当您这样做时,((I)s).Set(4, 4);您正在更改第二个,即堆中的那个。

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

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

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

推荐阅读