包含接口参数并在子类上操作的包装器方法

时间:2014-03-12 15:56:33

标签: c# generics

我有一个界面“I”,其中包含字段“ID”。从该界面,我有对象A,B,C,D来实现它。在一个完全独立的类数据库中,我有4个名为Foo的方法,它们在A,B,C和D上运行。

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

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

我必须为我的所有缓存执行此操作,总共大约有11个,所以我试图编写某种可以执行这些操作的通用方法。 Bar在I上运行,所以没有问题。我看到的唯一问题是Database.Foo,因为虽然有实现I的所有类型的Foo实现,但是编写一个简单的包装器:

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

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

编辑:根据要求,Database.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);

这样可行,但我更喜欢更优雅的东西,还有其他我可以做的事情来避免传递给代表吗?

1 个答案:

答案 0 :(得分:0)

如果您正在使用依赖注入,那么使用考虑您的类的方法注册实现接口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和桥接类实例(简单字典)之间的键值映射
  • 配置(配置文件中的类型之间的映射......)

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