如何在非泛型类ClassB中调用抽象泛型类classA的GetSomeData方法
解决方案
首先观察到GetSomeData方法的签名未使用泛型参数T,这是可以做非泛型适配的核心前提,以下是不同场景下的可选方案:
方案1:提取非泛型接口(最优解,无性能损耗、解耦性好)
给ClassA<T>抽一个不含泛型的公共接口,把GetSomeData定义在这个接口里,ClassB直接依赖这个非泛型接口即可。
// 新增非泛型接口 public interface IClassA { string GetSomeData(Guid ID); } // 让原有泛型ClassA实现该接口 public abstract class ClassA<T> : IInterface<T>, IClassA where T : new() { public string GetSomeData (Guid ID) { return somestring; } } // ClassB中直接依赖IClassA使用 public abstract class ClassB : InterfaceB { // 可以通过构造注入、方法参数传入或者直接实例化指定T的ClassA实现 private readonly IClassA _classA; // 构造注入示例 public ClassB(IClassA classA) { _classA = classA; } public void YourMethod() { Guid testId = Guid.NewGuid(); string result = _classA.GetSomeData(testId); } }
如果不需要依赖注入,也可以在调用时直接实例化指定具体T的ClassA,比如业务中T使用UserDto,就直接写new ClassA<UserDto>().GetSomeData(id)即可。
方案2:调用时指定具体泛型参数(适合无法修改ClassA定义的场景)
如果不允许改动ClassA的现有定义,只需要在调用GetSomeData时,给ClassA指定符合where T : new()约束的具体业务类型即可,不需要把ClassB改成泛型:
public abstract class ClassB : InterfaceB { public void YourMethod() { Guid testId = Guid.NewGuid(); // 替换为业务中实际用到的T类型即可 var classAInstance = new ClassA<YourConcreteType>(); string result = classAInstance.GetSomeData(testId); } }
这里的YourConcreteType需要是有无参构造函数的类,满足ClassA<T>的泛型约束即可。
方案3:反射调用(仅适合T类型运行时才能确定的极端场景)
如果T的类型要在运行时才能动态获取,可以用反射构造指定T的ClassA实例再调用方法,缺点是有性能损耗,优先选择前两个方案:
public abstract class ClassB : InterfaceB { public string DynamicCallGetSomeData(Type tType, Guid id) { // 构造泛型类型 Type genericType = typeof(ClassA<>).MakeGenericType(tType); // 实例化 object instance = Activator.CreateInstance(genericType); // 调用方法 var method = genericType.GetMethod("GetSomeData"); return (string)method.Invoke(instance, new object[] { id }); } }
内容的提问来源于stack exchange,提问作者mulki
相关产品推荐
相关产品推荐

