【发布时间】:2018-10-30 02:04:43
【问题描述】:
我有一个包含接口的第三方库(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
但这意味着我必须从两个接口实现每个方法。
这种方案是不能接受的,因为实际上这些接口(@987654342@,I2)包含了很多方法。
所以我的问题是: 如何创建一个允许我这样做的变量:
c.F1(); // ok
c.F2(); // ok
// c.F3(); // error is ok
?
【问题讨论】:
-
你确定你没有试图过度设计事情吗?我的意思是限制消费者对某些功能的访问是值得的,但是,我经常看到我的同事试图过度连接所有东西。也就是说,在我看来,界面最能描述通用性,不应该过多地用于限制访问或控制,尤其是当脏的小手指可以随意投掷时。
-
接口不应该过多地用于限制访问或控制 - @TheGeneral,我同意,但需要防止调用某些函数,因为它们执行导致程序崩溃。
标签: c# inheritance types casting type-conversion