Matthias Burger
Matthias Burger

Reputation: 5956

Generic property-list with any generic argument

I need to instantiate a list-property where the generic type can be anything.

So my Main-method looks like this: (In real, ParsingObject<T> are objects I get from a service)

public static void Main()
{
    Parser parser = new Parser();
    parser.AddAnObject(
        new ParsingObject<int>{PropertyName = "FirstProperty", Active=true, DefaultValue=1}
    );
    parser.AddAnObject(
        new ParsingObject<bool>{PropertyName = "SecondProperty", Active=false, DefaultValue=false}
    );
    parser.Parse();
}

ParsingObject gets any type (I think only string, bool, int,...) as generic. Now in my parser I need to add this object into a List<ParsingObject<T>> like:

public class Parser
{
    private readonly List<ParsingObject<T>> _listOfObjects = new List<ParsingObject<T>>();

    public void AddAnObject<T>(ParsingObject<T> item)
    {
        _listOfObjects.Add(item);
    }

    public void Parse()
    {
        foreach(var item in _listOfObjects.Where(w=>Active))
        {
            DoSomething(item);
        }
    }
}

but I know, I cannot set T as generic argument when instantiating the list (compiler is crying..). So I could solve this with using ArrayList - but then I can't access the properties of each object. (See the Parse()-method)

for completeness, here is my ParsingObject<T>-class:

public class ParsingObject<T>
{
    public string PropertyName { get; set; }
    public bool Active { get; set; }
    public T DefaultValue { get; set; }
}

Any idea how I could solve this? I cannot modify the ParsingObject<T>-class.

Upvotes: 0

Views: 1253

Answers (1)

slawekwin
slawekwin

Reputation: 6310

Depending on what exactly is your end goal, maybe something like this would be sufficient:

public class ParsingObjectBase
{
    public string PropertyName { get; set; }
    public bool Active { get; set; }
    public Type ValueType { get; protected set; }

    public object DefVal { get; protected set; }
}
public class ParsingObject<T> : ParsingObjectBase
{
    public object DefaultValue
    {
        get { return (T)DefVal; }
        set { DefVal = value; }
    }

    public ParsingObject()
    {
        ValueType = typeof(T);
    }
}

private readonly List<ParsingObjectBase> _listOfObjects = new List<ParsingObjectBase>();

public void AddAnObject<T>(ParsingObject<T> item)
{
    _listOfObjects.Add(item);
}

public void Parse()
{
    foreach(var item in _listOfObjects.Where(w=>w.Active))
    {
        DoSomething(item); //do what exactly?
    }
}

You obviously can't do without casting either to concrete ParsingObject<T> or DefVal value in this case, but you have Type information stored in one place and have access to your specific properties. Maybe changing ValueType to some kind of enum would be easier to use with switch?

Upvotes: 1

Related Questions