Nick.T
Nick.T

Reputation: 577

Abstract Generics and List of abstract

I haven't found my use case in the existing questions so here I go. I have an abstract class that has generics like this :

public abstract class aParameter<T>
{
    private T _parameter;

    public T Parameter
    {
        get { return _parameter;}
    }

    ...
}

Then I have my "Type" classes like this :

public class IntParameter : aParameter<Int32>
{
    public IntParameter(Int32 value)
    {
        _parameter = value;
    }
}

 public class TextParameter : aParameter<String>
{
    public TextParameter(String value)
    {
        _parameter = value;
    }
}

Now in my application code, I'd like to create a dictionary with the abstract generic class without specifying the generic type. Like this :

...
private Dictionary<Int32, aParameter> _paramDict = new Dictionary<Int32, aParameter>();
...

In a previous version, I used interfaces instead of abstract class for aParameter but I wanted to migrate it to abstract so that I could simplify my "Type" classes and not repeat identical code for each "Type".

Any thoughts here?

EDIT

I forgot to mention that it will be part of a library that is meant to be distributed among the company so I really need to secure the allowed types. I can't allow for just objects to be fed into my code.

Upvotes: 3

Views: 3263

Answers (3)

Steve
Steve

Reputation: 1316

The purpose of generic types is (among other things) that you can only write code once that can be used for multiple types. However, as C# is strongly types, the compiler needs to know what types it is dealing with in the generic class. This is why you have to specify the type of the generic (i.e. the type in angled brackets) If you don't specify the type of the generic then, in your example, the compiler wouldn't know the type of the Parameter property.

Depending on exactly what you're doing with it, there are a number of possible approaches:

  1. Use a Dictionary<int, object>. When reading the values, you can use a bunch of if/elses to check the specific type of the object and convert to the appropriate type. e.g.

    if(obj.GetType() == typeof(TextParameter)) { TextParameter p = obj as TextParameter // Do stuff } else if obj.GetType() == typeof(IntParameter)) { IntParameter p = obj as IntParameter // Do stuff }

  2. Have multiple dictionaries. Dictionary<int, TextParameter>, Dictionary<int, IntParameter>, etc.

  3. If there are methods/properties in aParameter that are not type dependent then move them to a lower level non-generic abstract class. This could give you at least some of your functionality without having to resort to type conversions.

Upvotes: 0

Jon Egerton
Jon Egerton

Reputation: 41569

You probably still going to need the non-generic interface (or nongeneric abstract base class as Brandon says), unless you drop to working with objects.

The reason is that aParameter<String> is not the same type as aParameter<int32> so you'll not be able to get them into the one dictionary without some help.

My preferred method around this is to declare a non-generic interface and use that as the basis for the dictionary, then implement it in each of your typed generics, and also in an abstract base class. That way you can inherit from the base class where possible, or just implement the interface if one of your types needs to inherit from something else - you get maximum flexibility.

Upvotes: 7

Brandon Moore
Brandon Moore

Reputation: 8780

Make a non-generic abstract base class and have your generic abstract class inherit from it.

Upvotes: 5

Related Questions