I've got a Dictionary<Type, HashSet<GenericType>> which I use to hold my data in, and I am trying to make a function that returns one of those HashSets given the generic type T : GenericType.
Basically
Dictionary<Type, HashSet<GenericType>> data;
public HashSet<T> Get<T>() where T : GenericType
{
    var tp = typeof(T);
    //....check if its in the dictionary, fill if not....
    return data[tp];
}
This isn't valid of course. But I am having a very hard time figuring out what I should do instead.
I feel like returning T is optimal though, since you then can do something like this:
Get<Derived>().Where(x => x.DerivedProperty == someValue)
But the only thing I thought of was to create a new HashSet<T> every time Get is called, and then using a foreach-loop cast and add every item from the already existing HashSet in the Dictionary, but this feels like such a waste?
Another idea is to skip HashSet and use another (covariant?) collection. But since these collections will hold lots of data, maybe it isn't the best idea either.
So in short I am wondering what the best approach for this problem is.
So this is the structure I got. The type which contains data is a type of service in my code structure. It will via reflection be loaded and initialized at runtime. From there I later use a ServiceFactory of sorts to get that service.
public class foo : Service
{
    public Dictionary<Type, HashSet<BaseClass>> data = new Dictionary<Type, HashSet<BaseClass>>();
    public T Get<T>() where T : BaseClass
    {
        var tp = typeof(T);
        if (!data.ContainsKey(tp))
        {
            data.Add(typeof(Derived), new HashSet<BaseClass>() { new Derived(), new Derived(), new Derived() });
        }
        return data[tp];//this wont compile.
    }
}
public class Derived : BaseClass
{
    public int ExampleVariable {get;set;}
}
public abstract class BaseClass
{
    // some things in here.
    public void DoCommonStuff()
    {
    }
}
class program
{
    static void Main(string[] args)
    {
        var service = ServiceFactory.GetService<foo>();
        var collection = service.Get<Derived>();
    }
}
 
  
                     
                        
I would just change the type of the dictionary, and cast inside your Get method. Definitely, definitely make your dictionary private though - then you can make sure that only your code (ideally only the Get method) can access it:
// Any data[typeof(Foo)] value will be a HashSet<Foo>. Only
// the Get method should access this dictionary.
private readonly Dictionary<Type, object> data = new Dictionary<Type, object>();
public HashSet<T> Get<T>() where T : GenericType
{
    var tp = typeof(T);
    object value;
    if (data.TryGetValue(tp, out value))
    {
        return (HashSet<T>) value;
    }
    var newSet = new HashSet<T>()
    // Populate newSet here
    data[tp] = newSet;
    return newSet;
}
I have a bit more discussion of a closely-related issue in a blog post.
 
                    See more on this question at Stackoverflow