将模板化基类通用子级传递给函数,不受模板类型限制

问题描述 投票:0回答:1

我有以下问题。我想创建一个具有可变类型属性的基类,该属性由基类和继承它的类在内部使用,如下所示:

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
}
    

如何解决此类问题?

c# generics inheritance
1个回答
0
投票
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 函数。

© www.soinside.com 2019 - 2024. All rights reserved.