包装器方法,它接受接口参数并对子类进行操作

本文关键字:子类 操作 参数 接口 方法 包装 | 更新日期: 2023-09-27 17:49:40

我有一个包含字段"ID"的接口"I"。从那个接口,我有对象A B C D来实现它。在一个完全独立的类Database中,我有4个名为Foo的方法,分别对a、B、C和d进行操作。

当为Foo编写一个方法时,它操作一堆包含子类缓存的Dictionary对象,我注意到我一遍又一遍地编写相同的代码。它看起来像

foreach(A in ACache.Values)
{
    int ID = A.ID;
    Database.Foo(A);
    int newID = A.ID;
    Bar(A);
}

我必须对所有的缓存都这样做,总共大约有11个,所以我试图写一些通用的方法来执行这些操作。Bar作用于I,所以没有问题。我看到的唯一问题是数据库。Foo,因为尽管对于所有实现I的类型都有Foo的实现,但编写一个简单的包装器如下:

void FooWrapper<T>(T obj) where T: I  { Database.Foo(obj); }

不符合要求。我怎样才能让它工作?如果可能的话,我宁愿避免使用反射。

编辑:按要求,数据库签名。Foo:

public bool Foo(ref A aItem); //returns true based on success of query
public bool Foo(ref B bItem); 
public bool Foo(ref C cItem); 

EDIT2:好的,我可以这样写FooWrapper:

FooWrapper<T>(IEnumerable<T> items, Func<T, bool> fooDelegate) where T : I
{
    foreach(T item in items)
    {
        int oldId = item.ID;
        fooDelegate(item);
        int newId = item.ID;
        Bar(item);
    }
}

并这样称呼它:

FooWrapper(ACache.Values, (Func<A, bool>) Database.Foo);

这是可行的,但我更喜欢更优雅的东西,我能做些什么来避免传递委托吗?

包装器方法,它接受接口参数并对子类进行操作

如果您正在使用依赖注入,那么将实现接口IDatabaseDoingStuffTo的组件注册为考虑您的类的方法将是微不足道的。

interface IDatabaseDoingStuffTo<T>{
    void DoStuff(Database db, T t);
}

那么在你的代码中你就会有

foreach(A in ACache.Values)
{
    process(db, A);
}
public void process(Database db, I i)
{
    int ID = i.ID;
    // retrieve IDatabaseDoingStuffTo
    var iddsti = retrieveDatabaseBridge(i);
    iddsti.DoStuff(db, i);
    int newID = i.ID;
    Bar(i);
}

retrieveDatabaseBridge可能来自:

  • 依赖注入
  • a类型和桥接类实例(简单字典)之间的键值映射
  • 配置(配置文件中类型之间的映射…)

所以有解决方案,但我们可能需要更多关于您目前可用的信息