我有以下问题。我想创建一个具有可变类型属性的基类,该属性由基类和继承它的类在内部使用,如下所示:
public abstract class BaseClass<T>
{
protected T Value { get; set; }//Not used outside of the inheriting classes
public abstract byte[] ToBinary();
}
public class MyClass1 : BaseClass<int>
{
public override byte[] ToBinary()
{
return BitConverter.GetBytes(Value);//We use the templated property internally here
}
}
public class MyClass2 : BaseClass<string>
{
public override byte[] ToBinary()
{
return Encoding.ASCII.GetBytes(Value);
}
}
当我想编写一个想要使用基类(MyClass1 或 MyClass2)的任何子级而不从外部访问模板化信息的函数时,就会出现问题,如下所示:
//Compiler requires us to provide the type for the BaseClass here
//We want to be able to pass multiple different BaseClass inheriting child types here
//f.e. MyClass1 and MyClass2 without restricting the usage to specific template type
public static void DoSomethingWithAnyClassInheritingBase(BaseClass b) {
//This implementation should not matter to us and we are not using the
//Templated params outside of this class
b.ToBinary();//Always returns binary and takes no arguments
}
如何解决此类问题?
public interface IBinaryConverter
{
byte[] ToBinary();
}
public abstract class BaseClass<T> : IBinaryConverter
{
protected T Value { get; set; }//Not used outside of the inheriting classes
public abstract byte[] ToBinary();
}
public class MyClass1 : BaseClass<int>
{
public override byte[] ToBinary()
{
//We use the templated property internally here
return BitConverter.GetBytes(Value);
}
}
public class MyClass2 : BaseClass<string>
{
public override byte[] ToBinary()
{
return Encoding.ASCII.GetBytes(Value);
}
}
public static void DoSomethingWithAnyClassInheritingBase(IBinaryConverter b) {
//This implementation should not matter to us and we are not using the
//Templated params outside of this class
b.ToBinary();//Always returns binary and takes no arguments
}
问题是根依赖关系是您定义了
BaseClass<T>
而没有 BaseClass
非通用。您可以将其定义为上面的接口,或者如果您不想使用接口,也可以同样包含非泛型定义,如下所示:
public abstract class BaseClass
{
public abstract byte[] ToBinary();
}
public abstract class BaseClass<T> : BaseClass
{
protected T Value { get; set; }//Not used outside of the inheriting classes
}
然后,您将能够实现 BaseClass,但仍将其实例传递给 DoSomethingWithAnyClassInheritingBase 函数。