Reputation: 3
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
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