【发布时间】:2015-01-12 15:32:10
【问题描述】:
我有一个接口 IFoo 定义了一些函数,一个抽象类 FooBase 实现了 IFoo 和一些内部函数,以及几个从 FooBase 派生的类 Foo。
我还有一个类 Bar,它应该从 FooBase 调用一个方法,但它的参数作为 IFoo 传递。所以一切看起来像这样:
public interface IFoo
{
// Some methods
}
public abstract class FooBase : IFoo
{
// Methods from IFoo
internal TInternalType SomeMethod();
}
public class Foo1 : FooBase
{
// ...
}
public class Bar
{
public void DoSomething(IFoo foo)
{
// This does not feel right:
TInternalType myT = (foo as FooBase).SomeMethod();
}
}
如前所述,这感觉不对,因为任何人都可以来,编写一个实现 IFoo 的 Baz 类并用它调用 DoSomething 将失败。
我还找到了this 问题/解决方案,以解决有关具有公共接口的内部内容的类似问题,但这不会改变某些第三方类实现 IFoo 会导致问题的问题,即我仍然有一个撒谎的 API。
另外,我可以更改 DoSomething 的类型以获取 FooBase 类型的参数并通过将构造函数设为内部来从第三方类中保护 FooBase,但我希望在我的公共 API 中只包含抽象,而不是实现。
简而言之,我要问:图书馆有没有办法只公开抽象(即图书馆的用户只使用这些抽象)但仍然访问内部成员?
背景:
我正在编写一个公开某些类型并使用另一个库 L 来实现其功能的库。使用 L 的事实是我想对我的图书馆用户隐藏的实现细节,所以当出于某种原因我必须用其他东西替换 L 时,我的用户不会注意到。
我现在有一些将向我的用户公开的 Foo 类,以及一个将与 L 一起使用的 Bar 类。对于每个 Foo 类,必须创建 L 中一个类的相应实例;但是单独的 Foo 类太不同了,它们每个都需要单独的逻辑来创建各自的 L 类。
这就是为什么我在 FooBase 中定义了一个内部抽象方法,并且每个 Foo 都实现了自己的方法来从 L 生成其类,因此 Bar 可以调用这个方法来获取它需要与 L 一起使用的东西。
也许有一种与内部重载方法完全不同的方法。
【问题讨论】:
-
如果你依赖
FooBase的实现,你应该使用它作为你的方法参数。 -
如果你真的想使用反射,但请接受上述评论。
-
如果您唯一担心的是
DoSomething会因为任何实现IFoo而不是从FooBase继承的东西而失败,那么为什么不呢:var probablyFooBase = foo as FooBase; if (probablyFooBase != null) { probablyFooBase.SomeMethod(); }? -
"i want to have only abstractions in my public API, not implementations."- 好吧,FooBase是abstract class,所以您的条件仍然满足。 -
InternalsVisibleToAttribute是否适用于您的情况(需要强签名的程序集)?