我定义了以下界面。
IDbContext
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; }
}
编译器抛出以下错误:
类型'T'必须是引用类型才能将其用作参数 泛型类型或方法中的“TEntity” 'System.Data.Entity.DbSet'TestContext.cs
类型'T'必须是引用类型才能将其用作参数 泛型类型或方法中的“TEntity” 'System.Data.Entity.DbSet'IDbContext.cs
方法的类型参数'TEntity'的约束 'System.Data.Entity.DbContext.Set()'必须匹配 接口方法的类型参数'T'的约束 'Domain.Logic.Repositories.IDbContext.Set()'。 请考虑使用显式接口实现 EntityFramework.dll
当我将约束添加到IDbContext接口中的Generic方法时,错误消失了:
public interface IDbContext<T> : IDisposable where T : class
{
DbSet<T> Set<T>() where T : class;
int SaveChanges();
}
我很困惑为什么我需要在类级定义时明确定义方法的约束?
更新 根据评论,我意识到我犯了错误。
我完全忽略了DbContext.Set()方法中的类型参数。泛型方法上的类型参数与其类/接口类型参数(如果有)不同,因此应该命名为不同。在我的情况下,我有几个问题:1)我有一个泛型接口与泛型类型的方法具有相同的参数名称。 2)泛型类型方法本身是在DbContext.Set()之后建模的,它有自己的约束,但这些约束没有应用于泛型方法本身。
我按照以下答案提供了选项3:
public interface IDbContext : IDisposable {
DbSet<T> Set<T>() where T : class
int SaveChanges();
}
HTH
答案 0 :(得分:6)
删除<T>
中Set<T>
中的DbSet<T> Set<T>()
或<{em>> 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();
}
或
IDbContext
Alternatively,从public interface IDbContext : IDisposable {
DbSet<T> Set<T>() where T : class
int SaveChanges();
}
删除通用参数:
{{1}}
根据您的comments,后者似乎更适合您的需求。