为什么我可以使用((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 { }
}
}
答案 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/