【问题标题】:Automatically cast interface to correct concrete type before overloading重载前自动转换接口以纠正具体类型
【发布时间】:2020-07-03 14:51:35
【问题描述】:

我有一个由多个具体类实现的接口和一个为每个具体类重载的方法(示例仅用于说明目的):

class IShape 
{
    /* ... */
}
class Square : IShape
{ 
    /* ... */ 
}
class Circle : IShape
{
    /* ... */
}
void toPng(Square a)
{
    /* ... */
}
void toPng(Circle b)
{
    /* ... */
}

这是我想做的:

/* Here i know that shape is castable to one of the concrete types */ 
Shape shape = Deserialize(jsonString);
toPng(shape) // Error : Cannot convert from 'IShape' to 'Square'

我可以尝试对每个具体类进行强制转换,但这并不理想。

try
{ 
    toPng( (Square)shape ) 
}
catch { /* ... */ }
try
{ 
    toPng( (Circle)shape ) 
}
catch { /* ... */ }

有没有办法在重载发生之前自动将接口转换为正确的具体类型?不知何故,我在互联网上找不到任何东西。

[edit] 我应该注意,在我的情况下,我宁愿不修改接口及其具体实现,所以将toPng() 放入接口合同不是我想要的。

【问题讨论】:

  • 要么将 toPng() 添加到您的 IShape 接口,要么作为虚拟方法添加到所有具体类的基类,具体类中的覆盖。
  • 对不起,我应该明确表示我不想修改基类,因为它们不是我直接拥有的代码

标签: c# interface overloading


【解决方案1】:

您想推迟成员查找,直到您知道变量的运行时类型。

这就是dynamic 的用途。它在运行时而不是编译时进行成员查找。

/* Here i know that shape is castable to one of the concrete types */ 
dynamic shape = Deserialize(jsonString);
toPng(shape)

虽然您需要注意 - 您实际上是在断言您知道它将在运行时找到合适的成员 - 如果成员查找实际上失败了,因为 shape 结果成为Elephant - 你会得到一个运行时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多