为什么不向上转换为具体类型的另一个常见接口

时间:2015-10-15 19:23:05

标签: c# interface casting upcasting

为什么你不能向另一个常见界面的另一种具体类型转发。我在linqpad中创建了这个例子。现在我可以理解,如果你在两个类之间有不同的属性,那么up up会因为无法完成对象而失败。但是在这个场景中我不明白为什么上传会失败。

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中有额外的属性,它无法弄清楚它会抛出。

2 个答案:

答案 0 :(得分:1)

因为您正在尝试转换为与其他第一个无关的其他类,它支持相同的接口。你要做的是在C#中不支持的某种Duck类型。

在您的情况下,您希望直接在界面上调用方法,而不使用类似的演员:

<div class="row" style="margin:0px; padding: 0px;"> <div class="status-icons-text-color temperature-data-icons"> <table> <tr> <td><div align=c enter data-toggle="tooltip" data-placement="bottom" title="first temperature"> <img src="images/icons/first_temp_icon_outline_white.png" style="max-width:20px;"> <div id="first_temp" style="padding-top: 10px; font-weight: bold;font-size: 12pt;">-- °C</div> </div></td> <td><div align=c enter data-toggle="tooltip" data-placement="bottom" title="second temperature"> <img src="images/icons/second_temp_icon_white.png" style="max-height:20px;"> <div id="second_temp" style="padding-top: 10px; font-weight: bold; font-size: 12pt;">-- °C</div> </div></td> <td><div align=c enter data-toggle="tooltip" data-placement="bottom" title="Third temperature"> <img src="images/icons/third_temp_white.png" style="max-height:20px;"> <div id="third_temp" style="padding-top: 10px; font-weight: bold; font-size: 12pt;">-- °C</div> </div></td> </tr> </table> </div> </div>

这就是为什么你要使用这个界面的原因。这是一个班级的合同&#34;它支持的功能&#34;。

答案 1 :(得分:1)

由于ConcreteAConcreteB一无所知(在您的情况下,因为它们可能对属性a有不同的实现),我建议您为ConcreteB实现这样的显式运算符:

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