C#中如何不指定类型使用泛型MyContext基类接收派生实例?
泛型DbContext基类的类型兼容问题
问题场景
我定义了两个继承自泛型基类MyContext<T>的EF Core上下文派生类:
public abstract partial class MyContext<T> : DbContext where T : DbContext { protected MyContext(DbContextOptions<T> options) : base(options) { } // MyContext的其他代码 } public class MyPrimaryContext : MyContext<MyPrimaryContext> { public MyPrimaryContext(DbContextOptions<MyPrimaryContext> options) : base(options) { } } public class MySecondaryContext : MyContext<MySecondaryContext> { public MySecondaryContext(DbContextOptions<MySecondaryContext> options) : base(options) { } }
在消费代码中尝试根据条件选择使用其中一个上下文时,编写了如下代码:
MyPrimaryContext originalContext; // 省略初始化代码 MySecondaryContext backupContext; // 省略初始化代码 MyContext resolvedContextToUse; if (<some condition>) { resolvedContextToUse = backupContext; } else { resolvedContextToUse = originalContext; }
但报错提示:Using the generic type 'MyContext' requires 1 type arguments。想知道是否可以定义不指定类型的泛型基类变量,让运行时自动解析类型,或是此处继承概念不适用?
解决方案
1. 新增非泛型基类/接口
MyContext<T>是泛型类,C#不允许直接使用未指定类型参数的泛型类型声明变量。你可以创建一个非泛型的基类或接口,让泛版MyContext<T>继承它:
// 新增非泛型基类 public abstract class MyContext : DbContext { protected MyContext(DbContextOptions options) : base(options) { } } // 泛型基类继承非泛型基类 public abstract partial class MyContext<T> : MyContext where T : DbContext { protected MyContext(DbContextOptions<T> options) : base(options) { } // 原有泛型基类的代码 }
之后就可以用MyContext resolvedContextToUse;声明变量,两个派生类都能正常赋值。
2. 直接使用DbContext作为变量类型
如果你的业务操作只需要DbContext提供的基础功能(如SaveChanges、DbSet访问等),可以直接用DbContext声明变量:
DbContext resolvedContextToUse; if (<some condition>) { resolvedContextToUse = backupContext; } else { resolvedContextToUse = originalContext; }
3. 明确泛型类型的规则
C#中,未指定类型参数的泛型类型(如MyContext)不是合法的可实例化/声明变量的类型,只有指定了类型参数的构造泛型类型(如MyContext<MyPrimaryContext>)才是有效类型。所以你无法直接用MyContext作为变量类型来接收不同泛型参数的派生类实例。
内容的提问来源于stack exchange,提问作者user736570
相关产品推荐
相关产品推荐

