У меня есть сторонняя библиотека (dll, созданная с использованием C #), которая содержит интерфейсы
public interface I1 {
void F1();
}
public interface I2 {
void F2();
}
public interface I3 {
void F3();
}
// and so on ...
и содержит класс
public class C : I1, I2, I3 // ...
{
public void F1() { } // implement I1.F1();
public void F2() { } // implement I2.F2();
public void F3() { } // implement I3.F3();
// and so on ...
}
Я добавил ссылку наэта библиотека в моем проекте в VisualStudio и создала экземпляр класса C
C c = new C();
c.F1(); // ok
c.F2(); // ok
c.F3(); // ok
Переменная c
позволяет вызывать методы всех интерфейсов (F1
, F2
, F3
, ...).
Чтобы создать переменную, позволяющую вызывать только методы интерфейса I1
, достаточно изменить тип переменной
I1 c = new C();
c.F1(); // ok
// c.F2(); // error is ok
// c.F3(); // error is ok
Но Теперь я хочу создать переменную некоторого типа, которая позволяет вызывать методы интерфейсов I1
, I2
и не позволяет вызывать методы других интерфейсов
I1_I2 c = new C();
c.F1(); // ok
c.F2(); // ok
// c.F3(); // error is ok
Для этого,Я создал интерфейс
public interface I1_I2 : I1, I2 { }
Однако компилятор не позволяет мне выполнить присвоение
I1_I2 c = new C(); // Compile error : Cannot implicitly convert type 'C' to 'I1_I2'.
Я попытался явное преобразование
I1_I2 c = (I1_I2)new C(); // Runtime error : InvalidCastException was unhandled.
, но этопреобразование не может быть выполнено, потому что класс C
не реализует I1_I2
(только I1
и I2
отдельно).
Одним из возможных решений этой проблемы может быть обертка класса
public class Wrapper : I1_I2
{
private C _c = new C();
public void F1() { _c.F1(); }
public void F2() { _c.F2(); }
}
// ---------------------------------
I1_I2 c = new Wrapper();
c.F1(); // ok
c.F2(); // ok
// c.F3(); // error is ok
, но это означает, что я должен реализовать каждый метод изоба интерфейса.Это решение неприемлемо, потому что на самом деле эти интерфейсы (I1
, I2
) содержат намного больше методов.
Поэтому мой вопрос: Как создать переменнуючто позволит мне сделать это:
c.F1(); // ok
c.F2(); // ok
// c.F3(); // error is ok
?