views:

99

answers:

4

Id' like to create a list of data that will be passed from method to method, however I can't use a struct because the data that will be contained in this list will vary depending on the input.

For example

if (x == 1) {
   a = 1 
   b = true   
   c = 42
   d = "hello"
}

if (x == 2) {
   a = 2
   b = 'g'
   c = "sup"
}

I believe my options are thus:

  1. Create an array or List of strings, and cast the data back to what it originally was from strings. This is messy and could lead to bugs of uninterpretable input, though wouldn't be so bad since it'd all be detected at runtime.
  2. Create a struct for each possibility - Is this even good practice?
  3. Somehow use generics. From what I know, while generics are type-safe yet not type-strict, they must be cast to types before being used. Eg if I wanted a List of items here, I'd need to cast them to strings much like would happen with solution 1, making this useless.

My question then, is which of these options is the best? Or is there an alternate option using some sort of generic type I don't know about? The number of possible variables in each case may change, as with their types. I'd like to be able to return a single List or Array to the calling method, so that it may appropriately deal with the result. It will know how to deal with each group of data based on the value of a, as it will be the 'action choice' identifier. I'm also aware that casting them to objects and back each time is very intensive so I'd rather avoid that.

This is probably pretty simple but it has me stumped...

+4  A: 

Since you don't know before hand what the list will contain, it looks like a good case for using an ArrayList.

If you want to get back to the values using a key, consider using a Hashtable.

Alfred Myers
A: 

Sorry, this is not a code related answer: there may be a faulty design hidden behind such a construct. Make sure you know what you are doing, otherwise things might fire back.

If not knowing the type of the fields you use beforehand really is required, this calls for an approach that saves the data with their type, like

struct foo {
    private object _value;
    private string _type;
    foo(string myType, object myValue) {
        _value = myValue;
        _type = myType;
    } 
}

and then using Generics to handle the business logic.

Olaf
A: 

You could represent the data items using a Dictionary/Hashtable and then add these dictionaries to a List.

You could also add extra type information into the dictionary value if needed.

pjp
+1  A: 

Basically you need a list typed to Object, and then yes, you're in a mode of casting back.

My question is, structurally, how will you know what indexes are of which type? This sounds like a painful solution at best.

If you really need to store differing types in the list, perhaps try a struct which contains a member of each type, as well as a flag indicating which data type is represented. Then use a generic collection for that struct. Something like (off the top of my head)

struct FooType
{
    public string StringValue;
    public bool BoolValue;
    public int IntValue;
    public char CharValue;

    public string DataType;

    // You'd probably want constructors too
}

Then the generic list:

var values = new List<FooType>();

Now you can add and remove entries in the list using that type, which would then indicate what the core data really is.

I still don't like the answer; it sounds like your design may be trying to do too much and there may be refactoring opportunities, but since I don't see much more of your code or intent, all I can do is answer what you've asked. :)

John Rudy