Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Method returning different generic collections

Tags:

c#

generics

Hi I have a Method like this:

        public T LoadR<T, K>()
        where T : ObservableCollection<K>, new()
        where K : IStoreElement, new() {
        T onC = new T();
        //....
        return (onC);
    }

Further I have a class XObservableCollection which derivies from ObservableCollection. It works as it is when I call:

Categories = LoadR<ObservableCollection<Category>,Category>();
Products = LoadR<XObservableCollection<Product>,Product>();

What I want to do is to make a call like this (avoid passing the K as extra parameter):

Categories = LoadR<ObservableCollection<Category>>();
Products = LoadR<XObservableCollection<Product>>();

I know that I could write an extension for it. But I curious if there is a way to achive this without it.

Manfred

like image 522
ManniAT Avatar asked Nov 14 '22 21:11

ManniAT


1 Answers

I don't think you can.

C# has a mechanism to understand generic agruments from method paramaters when used in it, but not from other generic arguments of the same method. It doesn't work.

Maybe you can change your signature to:

    private static ObservableCollection<K> LoadR<K>(.ObservableCollection<K> onC)
        where K : IStoreElement, new()
    {
        //....
        return onC;
    }

Usage would be:

    static void TestLoad()
    {
        var result1 = LoadR(new ObservableCollection<Something>());
        var result2 = LoadR(new DerivedClassFromObservableCollection<Something>());
    }

Which I agree is not that good, and I can se it's not what you are looking for.

But just because C# wouldn't let you try to infer the types from the generic arguments.

.....

The other way aroudn is to make it use a specific collection. I can see you don't want this even more.

So, one thing you can do is make it return IEnumerable instead, then you usage will be something like:

    static void TestLoad()
    {
        var result1 = new ObservableCollection( LoadR<Something>() );
        var result1 = new DerivedClassFromObservableCollection( LoadR<Something>() );
    }

Which may not be good also if you want to do fancy things with the collection itself, because you no-longer own it.

....

I would go for the very first option myself.

like image 63
Meligy Avatar answered Dec 19 '22 01:12

Meligy