c# - 带接口(interface)的扩展方法

标签 c# inheritance extension-methods

假设我们有这个模型:

public abstract class AbstractTableReferentielEntity {}
public class EstimationTauxReussite : AbstractTableReferentielEntity { }

我为所有继承自 AbstractTableReferentielEntity 的类创建了一个扩展方法。

public static EntityItemViewModel ToEntityItem<T>(this T entity)
    where T : AbstractTableReferentielEntity {}

但是对于一种特定类型的 AbstractTableReferentielEntity(如 EstimationTauxReussite),我想执行特定的操作,因此我创建了第二个扩展方法。

 public static EntityItemViewModel ToEntityItem(this EstimationTauxReussite entity) {}

所有扩展方法都在同一命名空间中声明。

之后,我使用 Entity Framework 从数据库中检索一些数据:

protected List<EntityItemViewModel> GetAllActifEntityItem<T>()
    where T : AbstractTableReferentielEntity
{
    return Context
        .Set<T>()
        .Where(item => item.IsActif)
        .Select(item => item.ToEntityItem())
        .ToList();
}

它编译。<​​/p>

当 T 在运行时是 EstimationTauxReussite 类型时,当我调用 Select(item => item.ToEntityItem()) 时,它会进入错误的方法 ToEntityItem。它没有涉及最具体的扩展方法。有任何想法吗 ?

最佳答案

原因是扩展方法是“语法糖”,即它们是编译器的把戏。你的线路:

.Select(item => item.ToEntityItem())

被编译器有效地转换为:

.Select(item => StaticClassWithExtensionMethod.ToEntityItem(item))

然后变成了IL。这意味着 item 的类型必须在编译时确定,而不是运行时。因此,使用 AbstractTableReferentielEntity 版本的扩展方法,因为这是在编译时与类型匹配的方法。

关于c# - 带接口(interface)的扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31559766/

相关文章:

c# - 类库项目中的扩展方法

c# - 添加时获取DBEntityEntry的主键

c#-4.0 - 使用动态关键字调用子类方法

c++ - 在不知道类成员的情况下从基类实例创建派生类实例

c++ - 用户定义数据类型的大小和继承

c#-3.0 - 什么时候使用扩展方法是一个好习惯?

c# - 依赖注入(inject) DbContext 是否在给定请求实例中使用它的所有类之间共享?

c# - 需要存储一堆常量整数值,类只有 const 或更好的东西?

c# - 让 Single 和 SingleOrDefault 抛出更简洁的异常

c# - 我将如何为 System.Data.Linq.Table<T> 编写扩展方法?