c# - 包含通用方法的通用接口(interface)需要相同的约束吗?

标签 c# entity-framework generics

我定义了以下接口(interface)。

IDb上下文

public interface IDbContext<T> : IDisposable where T : class
{
    DbSet<T> Set<T>();
    int SaveChanges();
}

它是由 TestContext 间接实现的,注意 TestContext 派生自 System.Data.Entity.DbContext。

public class TestContext: DbContext,IDbContext<Foo>
{

}

Foo 是一些实体

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
}

编译器抛出以下错误:

The type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method 'System.Data.Entity.DbSet' TestContext.cs

The type 'T' must be a reference type in order to use it as parameter 'TEntity' in the generic type or method 'System.Data.Entity.DbSet' IDbContext.cs

The constraints for type parameter 'TEntity' of method 'System.Data.Entity.DbContext.Set()' must match the constraints for type parameter 'T' of interface method 'Domain.Logic.Repositories.IDbContext.Set()'. Consider using an explicit interface implementation instead.
EntityFramework.dll

当我将约束添加到 IDbContext 接口(interface)中的通用方法时,错误消失了:

public interface IDbContext<T> : IDisposable where T : class
{
    DbSet<T> Set<T>() where T : class;
    int SaveChanges();
}

我很困惑为什么在类级别定义方法时需要显式定义方法的约束?


更新 根据评论,我意识到我所犯的错误。

我完全忽略了 DbContext.Set() 方法的类型参数。泛型方法的类型参数与其类/接口(interface)类型参数(如果有的话)不同,因此应该命名为不同的。在我的例子中,我遇到了几个问题:1) 我有一个通用接口(interface)和一个具有相同参数名称的通用类型方法。 2) 泛型类型化方法本身是在 DbContext.Set() 之后建模的,它有自己的约束,但这些约束并未应用于泛型方法本身。

我选择了下面答案中提供的选项 3:

public interface IDbContext : IDisposable {
DbSet<T> Set<T>() where T : class
int SaveChanges();

HTH

最佳答案

删除 <T>Set<T>DbSet<T> Set<T>() T Set<T> 中的不同名称你应该没事的。否则,您将定义一个 T这与 T 不同 IDbContext<T> 中的参数.这就是编译器需要第二个约束的原因,它认为它是一个不同的 T .因此,您需要以下两个选项之一。第一:

public interface IDbContext<T> : IDisposable where T : class {
    DbSet<T> Set();
    int SaveChanges();
}

public interface IDbContext<T> : IDisposable where T : class {
    DbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
}

Alternatively , 从 IDbContext 中删除通用参数:

public interface IDbContext : IDisposable {
    DbSet<T> Set<T>() where T : class
    int SaveChanges();
}

基于您的 comments ,后者似乎更适合您的需求。

关于c# - 包含通用方法的通用接口(interface)需要相同的约束吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17181449/

相关文章:

c# - 当我运行 WPF MVVM 应用程序时,显示主窗口的两个实例

c# - 在 Adob​​e Reader 中打开 PDF,而不是在浏览器中

linq - 学习 LinqToSql 还是坚持使用 ADO.NET?

c# - 我可以将静态方法调用内联到 EF 查询吗

java - 我可以从泛型类型参数中获取 .class 吗?

c# - 如何使用 C# 打印 pdf

c# - 如何使用 entitystate.modified 更新外键?

c++ - 用于操作 Base/Derived 对象容器的函数

java - 我可以定义 Map<String, List< 吗?扩展 BaseView>> 以便我可以从 map 中 get() 列表而无需未经检查的转换?

c# - 解析 XML 数据时出错