Приведение между интерфейсами, чьи подписи интерфейса одинаковы - PullRequest
3 голосов
/ 24 февраля 2012

Возможно ли приведение от одного интерфейса к другому, если подписи обоих интерфейсов одинаковы?Приведенный ниже источник дает исключение 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 ]

9 голосов
/ 24 февраля 2012

Возможно ли приведение от одного интерфейса к другому, если подписи обоих интерфейсов одинаковы?

Нет. Это совершенно разные типы для CLR и C #.

Вы можете создать «мостовой» тип, который обертывает реализацию IFirst и реализует ISecond делегированием или наоборот.

5 голосов
/ 24 февраля 2012

Как Джон Скит уже ответил , нет, вы не можете.

, если ваша проблема заключается в написании действительно общего кода и если вы не контролируете интерфейсы (как в решение, предложенное Baboon ), вы все равно можете сделать это двумя способами в C #:

1 - Reflection

... используя отражение, чтобы запросить нужный методдля вызова:

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
0 голосов
/ 24 февраля 2012

Один из способов, о котором я могу думать, это:

public interface IDoSomething
{
   string DoSomething();
}

public interface IFirst : IDoSomething {}

public interface ISecond : IDoSomething {}

Затем вместо приведения к IFirst или ISecond приведите к IDoSomething.

...