提问人:Brendan Lynn 提问时间:8/9/2023 最后编辑:DaiBrendan Lynn 更新时间:8/9/2023 访问量:42
从类型到未实现的显式强制转换接口编译,但在运行时失败 [duplicate]
Explicit Cast From Type to Not Implemented Interface Compiles but Fails in Runtime [duplicate]
问:
我有一个类和一个接口,如下所示:
internal class DoStuff
{
public int X { get; }
public void Do() => WriteLine(X);
public DoStuff(int X) => this.X = X;
}
internal interface IDoStuff
{
void Do();
}
该类不实现接口。因此,不存在隐式转换。但是,Visual Studio 的 Intellisense 表示“确实存在显式转换”。这对我来说是有道理的,因为如果一个接口具有一个类的所有相同方法,那么你就没有理由不能从类转换到接口。从逻辑上讲,我推断,您可以在类型声明中专门实现接口的唯一原因是显式实现。DoStuff
IDoStuff
我读了这篇文章,它声称这是不可能的。但是,它是在 2011 年编写的,因此我认为 C# 从那时起就发生了变化。C# 5.0 于 2012 年发布,一年后,我使用的是 C# 11.0。因此,为了验证我的理论,我尝试创建并运行以下 C#(.NET 6 顶级代码):
// Program.cs:
using static System.Console;
DoStuff d = new(2);
IDoStuff i = (IDoStuff)d;
i.Do();
return;
代码编译良好,但是当我尝试运行它时,它在第三行抛出了一个:InvalidCastException
System.InvalidCastException
:无法将类型的对象转换为类型。DoStuff
IDoStuff
这没有意义。链接的帖子毕竟还正确吗?
如果是这样,我有三个问题。
- 如果强制转换无论如何都不会成功,为什么 C# 编译器不会引发生成错误?
- 为什么在 C# 中仍然不支持从具有同名函数的类强制转换为未实现的接口?有什么滞留?
- 我依稀记得在某处读到,可以在具有相同元素的不同类之间显式转换。这是真的吗?如果是这样,有什么区别?
如果不是,为什么演员不工作?
以下是完整的组合代码:
https://dotnetfiddle.net/WfAHC4
using static System.Console;
DoStuff @do = new(2);
IDoStuff iDo = (IDoStuff)@do;
WriteLine("a");
iDo.Do();
WriteLine("b");
ReadKey(true);
internal class DoStuff
{
public int X { get; }
public void Do() => WriteLine(X);
public DoStuff(int X) => this.X = X;
}
internal interface IDoStuff
{
void Do();
}
答:
2赞
vatbub
8/9/2023
#1
你的意思叫做鸭子打字,像 Go 这样的语言就用它:如果它像鸭子一样走路,那它一定是鸭子,对吧?但是,C# 不支持此功能。相反,您需要显式实现接口。编译器通过不允许隐式转换来警告您。通过使用显式转换,你基本上是在告诉编译器“闭嘴,我知道我在做什么”,因此,编译器会关闭并信任你。
评论
This made sense to me,
不,这没有意义。仅仅因为一个类型具有与另一个类型具有相同名称或签名的方法,并不意味着它继承或实现该其他类型。或者这些方法以任何方式相关。 没有。这在任何强类型语言中都不受支持。Java 和 C++ 都不允许这样做What's the holdup
WriteLine
using static System.Console;