views:

50

answers:

1

I have many T arrays to read. Each T array can represent data of type A, B or C. A: A list of T B: A single T C: Exactly three T

When I read a T array, I will be able to get a list of T, and determine by reading the first T in the list whether it's of type A, B or C. I thought of two possible approaches and would like to know their merits and cons.

1)

enum {A, B, C};

class X {
    enum dataType;//A, B or C
    List<T> data;//just store all as list of T
    //other essential methods/properties
    //throws exception if an instance cannot fit into either A, B or C.
    X(T[] input)
    {
        //read input
    }
}

2)

abstract class X
{
    abstract int length{get;}
    //and other common essential methods/properties
}
class A : X
{
    List<T> data;
}
class B : X
{
    T data;
}
class C : X
{
    T data1, data2, data3;
}
class ConcreteX: X
{
    List<T> data;
    ConcreteX(T[] input)
    {
        //reads input and stores T(s) into data
    }
}
class XFactory
{
    getX(T[] input)
    {
        ConcreteX conX = new ConcreteX(input);
        //depending on whether it's A, B or C, create an instance of A, B, 
        //or C and map the corresponding fields from conX to the instance.
        //return that instance
    }
}
A: 

Well, if you need to have the generic class accept only a range of specific types then it might be easier to record the accepted types within an array. As you have not specified a specific language I will use c#, although I cannot guarantee it can be done with other lanaguages. I suppose if the language has the ability to at runtime create instances of the type they also should have the abilty to check against the type

private static List<Type> _acceptedTypes = { typeof(Type1), typeof(Type2) ... }

X(T[] input)
{
   if(!_acceptedTypes.Contains(typeof(T)))
   {
        throw new SomeException();
   }
   ...
}

Although personally this is not truely ideal as it is a runtime check (i.e. you only know about it when you try to use the class). It would be better to be able to apply constraints in a generic way which .net has but only against one type (which isn't helpful in your case).

aqwert