Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pass templated base class generic child to function without restricting by the template type

I have the following problem. I want to create a baseclass with variable type property that is used internally by the base class and classes that inherit from it as follows:

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);
    }
}

The problem arises when I would like to write a function that wants to use any child of the baseclass (MyClass1 or MyClass2) without accessing the templated information from the outside as follows:

//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
}
    

How could I get around this kind of problem?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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
}

The problem is the root dependency is that you have defined BaseClass<T> without a BaseClass non generic. You could define it as an interface as above or you could equally include a non generic definition as follows if you don’t want to use an interface:


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
}

You would then be able to implement BaseClass but still pass instances of it to the DoSomethingWithAnyClassInheritingBase function.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading