10

我有以下情况:

我有三个班级,我们称它们ABC。它们的共同点是它们继承自同一个接口,ISomeInterface并且它们是使用 Entity Framework 映射到实体的类。

我有一个接收实现此接口的对象列表的方法,但对象本身将是AB的实例C

方法外壳看起来像这样

public void MyMethod(List<ISomeInterface> entityList)
{
  foreach(var entity in entityList)
  {
    ProcessEntity(entity);
  }
}

现在,问题出在ProcessEntity方法上。这是一个通用方法,需要根据类型或实体从数据库中检索匹配元素的表,所以它看起来像这样:

public void ProcessEntity<T>(T entity)
{
  using( var repository = new DbRepository())
  {
    var set = repository.Set<T>();
    ...
  }
}

问题是该行var set = repository.Set<T>();失败,因为TISomeInterface这种情况下,而不是实际类型(ABC,所以它给出了一个与给定类型无关的异常,这是可以理解的。

所以我的问题是:如何使用列表中对象的实际类型而不是它们实现的接口类型来调用 ProcessEntity。

4

3 回答 3

14

您可以dynamic在将实体传递给 ProcessEntity 时应用关键字。在这种情况下,实体的实际类型将在运行时确定。

public void MyMethod(List<ISomeInterface> entityList)
{
  foreach(var entity in entityList)
  {
    dynamic obj = entity;
    ProcessEntity(obj);
  }
}
于 2012-05-31T09:33:59.413 回答
2

好吧,您可以使用类似访问者的技巧并使用以下解决方法:

  1. 定义一个Process(EntityProcessor ep)方法ISomeInterface
  2. A以as (以及与andep.ProcessEntity<A>(this)中的相同方式)实现它BC
  3. 而不是ProcessEntity(entity)在你的循环中,只需调用entity.Process(this).

(方法名称可能不是最干净的,但你应该明白)

于 2012-05-31T09:38:52.297 回答
2

您可以使用反射来获取泛型方法定义,然后调用它,例如:

var method = typeof(ClassContainingProcessEntity)
    .GetMethod(ProcessEntity)
    .MakeGenericMethod(entity.GetType);
method.Invoke(this, entity);

您可以按类型缓存该方法,如果性能至关重要,您可以在运行时使用某种委托工厂对其进行编译。

或者,您可以使用访客模式

于 2012-05-31T09:39:58.507 回答