c# - 再次在接口中构造;为什么我可以像上课一样使用它?
问题描述
为什么我可以使用 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 { }
}
}
解决方案
当您进行强制转换时,通过复制创建(I)s
另一个实例并将其放入堆中,因为接口是引用类型。所以此时你有两个实例:一个在堆栈中,另一个在堆中。S
s
S
因此,当您这样做时,((I)s).Set(4, 4);
您正在更改第二个,即堆中的那个。
最后Console.WriteLine(s);
是打印出第一个,堆栈中的那个。
要获得正确的输出,您必须执行以下操作:
var i = (I)s;
i.Set(4, 4);
Console.WriteLine(i);
推荐阅读
- android - Epson Android SDK 打印错误!非法表格数据
- scrapy - Scrapy 忽略每个蜘蛛的自定义设置
- angular - 将文件(图像)从 Angular 8 发送到 Spring Boot App
- c - 如何在 Linux 上测量 C 程序中文件 I/O 的执行时间?
- hadoop - Greenplum PXF 是否支持 HDFS 短路读取?
- java - 如何使用 H2 嵌入式数据库获取序列中的下一个值?
- postgresql - postgres 转储显示重复的功能
- c# - 如何在 SQL Server 中自定义 Serilog 字段?
- java - 如何从 mavens .m2 文件夹中排除读取 settings.xml
- python - 从 Python 中打开的登录表单保存 Web 会话