如何在不限制泛型类型的前提下传递泛型基类子类给函数
解决方案
要解决这个问题,核心是给所有泛型子类提供一个非泛型的公共契约,让函数可以基于这个契约接收任意子类实例。以下是两种常用实现方式:
方式一:使用非泛型抽象基类
创建一个不带泛型参数的抽象基类,把ToBinary方法定义在这里;让原泛型基类继承这个非泛型基类,泛型相关的属性和逻辑保留在泛型基类内部:
// 非泛型抽象基类,定义公共行为 public abstract class BaseClass { public abstract byte[] ToBinary(); } // 泛型基类继承非泛型基类,保留内部泛型属性 public abstract class BaseClass<T> : BaseClass { protected T Value { get; set; } } // 子类实现不变 public class MyClass1 : BaseClass<int> { public override byte[] ToBinary() { return BitConverter.GetBytes(Value); } } public class MyClass2 : BaseClass<string> { public override byte[] ToBinary() { return Encoding.ASCII.GetBytes(Value); } } // 现在函数可以接收任意子类实例 public static void DoSomethingWithAnyClassInheritingBase(BaseClass b) { b.ToBinary(); }
方式二:使用接口
定义一个包含ToBinary方法的接口,让泛型基类实现该接口。这种方式更灵活,因为C#支持多接口实现:
// 定义公共接口契约 public interface IBinaryConvertible { byte[] ToBinary(); } // 泛型基类实现接口,内部泛型属性保留 public abstract class BaseClass<T> : IBinaryConvertible { protected T Value { get; set; } public abstract byte[] ToBinary(); } // 子类实现不变 public class MyClass1 : BaseClass<int> { public override byte[] ToBinary() { return BitConverter.GetBytes(Value); } } public class MyClass2 : BaseClass<string> { public override byte[] ToBinary() { return Encoding.ASCII.GetBytes(Value); } } // 函数接收接口类型参数 public static void DoSomethingWithAnyClassInheritingBase(IBinaryConvertible obj) { obj.ToBinary(); }
为什么原写法不生效?
C#中,BaseClass<int>和BaseClass<string>是两个完全不同的具体类型,它们的共同父类是object,而非一个不存在的非泛型BaseClass。因此编译器无法将不同泛型参数的子类统一视为BaseClass类型,必须通过非泛型基类或接口建立公共契约。
内容的提问来源于stack exchange,提问作者The amateur programmer
相关产品推荐
相关产品推荐

