mlsker863
mlsker863

Reputation: 3

C# avoid redundancy - convert derived type to base generic type and access common property

I am beginning in C# and having some difficulties to solve the following problem.

Context :

Here is the code for the abstract classes SuperClass and MyGenericType :

public abstract class SuperClass<T> where T : MyGenericType
{
    public SuperClass()
    {
         Values = new List<T>();
    }
    public List<T> Values {get; set;}

    //some other properties 
}
public abstract class MyGenericType
{
    public int property1 {get; set;}
    public int property2 {get; set;}
}

Here is the code for class A and ValuesA : (NB class B (resp. C) and ValuesB (resp. ValuesC) have the same template only properties change (such as propertyA1 or propertyValuesA1)

public class A : SuperClass<AListValuesType>
{
    public A()
    {
        Values = new List<ValuesA>();
    }
    public int propertyA1 {get; set;}
    public bool propertyA2 {get; set;}
}

public class ValuesA : MyGenericType
{
    public bool propertyValuesA1;
    //some other properties
}

Problem : In my process, I have three objects of type A, B and C (accessible in all my ScriptMain class) where approximately the same transformations are applied. In order to avoid redundancy, I would like to use a common local variable at some point to store objects of type A, B and C and use it just as any object of type A, B or C.

Here is an example of my use with only object A and I need to do exactly the same with object B and C.

public class ScriptMain
{
    private A apiResultA;
    private B apiResultB;
    private C apiResultC;

    //some stuff

    public bool NextRow(string request)
    {
        //I would like to be able to have a variable apiResult that could store either apiResultA, apiResultB or apiResultC according to request value
        if (apiResultA != null)
        {
            //Need to be able to check if apiResultA.Values.Count=0
            //lot of generic stuff working for apiResultA, apiResultB and apiResultC
        }
        else
        {
            //lot of generic stuff working for apiResultA, apiResultB and apiResultC
        }
    }
}

I have tried to cast my variable, to use interfaces... But I have not been able to solve my problem and I have no idea where to look next.

Thank you for reading this !

Upvotes: 0

Views: 67

Answers (1)

Michael
Michael

Reputation: 1276

You can use an interface with covariance (out T):

public interface ISuperClass<out T> where T : MyGenericType
{
    IEnumerable<T> ValuesEnumerator { get; }  // IList dosen't support covariance, we have to use IEnumerable
    // Some other properties in your SuperClass 
}

SuperClass implements ISuperClass:

public abstract class SuperClass<T> : ISuperClass<T> where T : MyGenericType
{
    public SuperClass()
    {
        Values = new List<T>();
    }
    public List<T> Values { get; set; }
    public  IEnumerable<T> ValuesEnumerator => Values;
}

Now you can cast your results to ISuperClass<MyGenericType>:

public class ScriptMain
{
    private A apiResultA;
    private B apiResultB;
    private C apiResultC;

    //some stuff

    public bool NextRow(string request)
    {
        ISuperClass<MyGenericType> result = apiResultA;   // ISuperClass is covariant, so you can cast SuperClass<ValuesA> to ISuperClass<MyGenericType>
        if (result != null)
        {
            if (result.ValuesEnumerator.Count() == 0) { }
        }
    }
}

Upvotes: 1

Related Questions