在接口签名相同的接口之间进行转换

时间:2012-02-24 09:22:50

标签: c# .net casting

当两个接口的签名相同时,是否可以从一个接口转换为另一个接口?以下来源提供Unable to cast object of type 'ConsoleApplication1.First' to type 'ConsoleApplication1.ISecond'.例外。

class Program
{
    static void Main(string[] args)
    {
        IFirst x = new First();
        ISecond y = (ISecond)x;
        y.DoSomething();
    }
}

public interface IFirst
{
    string DoSomething();
}

public class First : IFirst
{
    public string DoSomething()
    {
        return "done";
    }
}

public interface ISecond
{
    string DoSomething();
}

3 个答案:

答案 0 :(得分:9)

  

当两个接口的签名相同时,是否可以从一个接口转换为另一个接口?

没有。就CLR和C#而言,它们是完全不同的类型。

您可以创建一个“桥”类型,它包含IFirst的实现并通过委派实现ISecond,反之亦然。

答案 1 :(得分:5)

作为Jon Skeet already answered,不,你不能。

如果您的问题是编写真正的通用代码,并且如果您不控制接口(如solution proposed by Baboon中所述),您仍然可以在C#中执行以下两种方式:

1 - 反思

...使用反射查询您要调用的方法:

object x = new First();

Type t = x.GetType();
MethodInfo mi = t.GetMethod("DoSomething");
mi.Invoke(x, new object[]{}); // will call x.DoSomething

2 - 动态(C#4)

在C#4中,使用dynamic关键字在运行时而不是编译时解析调用:

object x = new First();

dynamic d = x ;   // every call through d will be resolved at runtime
d.DoSomething() ; // compiles (but will throw if there is no 
                  // "DoSomething" method

答案 2 :(得分:0)

我能想到的一种方式是:

public interface IDoSomething
{
   string DoSomething();
}

public interface IFirst : IDoSomething {}

public interface ISecond : IDoSomething {}

然后转而使用IFirst或ISecond,而不是强制转换为IDoSomething。