C# 调用作为接口传递的对象的内部方法
本文关键字:对象 内部 方法 调用 接口 | 更新日期: 2023-09-27 18:37:17
我有一个定义一些函数的接口IFoo,一个实现IFoo和一些内部函数的抽象类FooBase,以及几个从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将失败。
我还发现了这个问题/解决方案,以解决有关公共接口的内部内容的类似问题,但这不会改变某些实现 IFoo 的第三方类会导致问题的问题,即我仍然有一个说谎的 API。
或者,我可以更改 DoSomething 的类型以采用 FooBase 类型的参数,并通过使构造函数成为内部构造函数来保护 FooBase 免受第三方类的影响,但我只想在我的公共 API 中具有抽象,而不是实现。
简而言之,我要问:有没有办法让库只公开抽象(即库的用户只使用这些抽象)但仍然访问内部成员?
背景:
我正在编写一个公开某些类型的库,并使用另一个库 L 来实现其功能。使用 L 的事实是一个实现细节,我想对我的库用户隐藏,所以当在某些时候由于某种原因我不得不用其他东西替换 L 时,我的用户不会注意到。
我现在有一些 Foo 类将公开给我的用户,还有一个 Bar 类将与 L 一起使用。对于每个类 Foo,必须从 L 创建一个类的相应实例;但是单独的 Foo 类差异太大,它们都需要单独的逻辑来创建各自的 L 类。
这就是为什么我在 FooBase 中定义了一个内部抽象方法,每个 Foo 都实现了自己的方法来从 L 生成它的类,所以 Bar 可以调用这个方法来获取它需要处理 L 的东西。
也许有一种与内部重载方法完全不同的方法。
避免向用户公开你的基类,为什么不创建另一个从IFoo
派生的接口,称之为类似IFooWithSomeMethod
,添加一个SomeMethod
方法,并在FooBase
中实现该接口? 然后Bar.DoSomething
可以采取IFooWithSomeMethod
而不是IFoo
.
顺便说一句,很抱歉在第一遍中搞砸了一些名字。 希望我现在把一切都理顺了。
接口的全部意义在于展示实现的能力。如果需要访问实现的内部成员,则应让代码的使用者知道它们不是真正的内部成员(通过遵循此处的其他答案,或者例如使用接口隔离并仅传递单个角色接口),或者将它们保留为真正的内部成员。在您的情况下,我认为它应该封装在FooBase
类中。
我想 DoSomething
方法也会对IFoo
实现做其他事情。无论Bar
对从内部方法返回的内部类型执行什么操作,都可能FooBase
发生在其他IFoo
方法之一中。这里的指导原则是告诉,不要问。
如果FooBase
是一个特殊情况(所以你不想要decalare IFooWithDoSomething
),需要额外的调用,你可以实现一个扩展IFoo
,像这样:
public static class FooExtensions {
public static void DoSomething(this IFoo value) {
FooBase special = value as FooBase;
if (null != special)
special.SomeMethod();
}
}
public class Bar
{
public void DoSomething(IFoo foo)
{
// Extension is called
foo.SomeMethod();
}
}