为什么不向上转换为另一个通用接口的具体类型
Why won't upcast to concrete type of another common interface
为什么不能向上转换为另一个通用接口的不同具体类型。我在 linqpad 中创建了这个示例。现在我可以理解,如果您在两个 类 之间具有不同的属性,向上转换将失败,因为它无法完成对象。但是在这个场景中,我不明白为什么向上转换会失败。
void Main()
{
ICommon test = new ConcreteA();
((ConcreteA)test).a.Dump();
// this errors with: Unable to cast object of type 'ConcreteA' to type 'ConcreteB'.
((ConcreteB)test).a.Dump();
}
public interface ICommon
{
string a {get; }
}
public class ConcreteA : ICommon
{
public string a {
get{ return "Concrete A"; }
}
}
public class ConcreteB : ICommon
{
public string a {
get{ return "Concrete B"; }
}
}
编译器是否应该能够将其视为从 double 转换为 int,如果 double 对于 int 来说太大,它会抛出异常,但如果可以进行转换,编译器会做吧。为什么编译器不尝试将 ConcreteA 作为 ConcreteB 加载,如果在 ConcreteB 中有它无法弄清楚的额外属性,那么它会抛出。
因为您正在尝试转换为另一个 class,它与支持相同接口的第一个无关。您正在尝试做的是某种 C# 不支持的 Duck 类型。
在您的情况下,您希望直接在接口上调用方法而不进行强制转换,例如:
test.a.Dump()
这就是您使用该界面的首要原因。这是一份class"what capabilities it supports".
的合同
由于 ConcreteA
对 ConcreteB
一无所知(在你的情况下,因为它们可能对 属性 a
有不同的实现),我建议你为混凝土 B 像这样:
public class ConcreteA
{
/* rest of your code ... */
public static explicit operator ConcreteB(ConcreteA instance)
{
// implement converting from ConcreteA to ConcreteB
}
}
有关显式运算符的更多信息:https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx
为什么不能向上转换为另一个通用接口的不同具体类型。我在 linqpad 中创建了这个示例。现在我可以理解,如果您在两个 类 之间具有不同的属性,向上转换将失败,因为它无法完成对象。但是在这个场景中,我不明白为什么向上转换会失败。
void Main()
{
ICommon test = new ConcreteA();
((ConcreteA)test).a.Dump();
// this errors with: Unable to cast object of type 'ConcreteA' to type 'ConcreteB'.
((ConcreteB)test).a.Dump();
}
public interface ICommon
{
string a {get; }
}
public class ConcreteA : ICommon
{
public string a {
get{ return "Concrete A"; }
}
}
public class ConcreteB : ICommon
{
public string a {
get{ return "Concrete B"; }
}
}
编译器是否应该能够将其视为从 double 转换为 int,如果 double 对于 int 来说太大,它会抛出异常,但如果可以进行转换,编译器会做吧。为什么编译器不尝试将 ConcreteA 作为 ConcreteB 加载,如果在 ConcreteB 中有它无法弄清楚的额外属性,那么它会抛出。
因为您正在尝试转换为另一个 class,它与支持相同接口的第一个无关。您正在尝试做的是某种 C# 不支持的 Duck 类型。
在您的情况下,您希望直接在接口上调用方法而不进行强制转换,例如:
test.a.Dump()
这就是您使用该界面的首要原因。这是一份class"what capabilities it supports".
的合同由于 ConcreteA
对 ConcreteB
一无所知(在你的情况下,因为它们可能对 属性 a
有不同的实现),我建议你为混凝土 B 像这样:
public class ConcreteA
{
/* rest of your code ... */
public static explicit operator ConcreteB(ConcreteA instance)
{
// implement converting from ConcreteA to ConcreteB
}
}
有关显式运算符的更多信息:https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx