Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot implicitly convert type error in generic method

Tags:

c#

generics

I have a problem with my generic method:

    public ReadOnlyObservableCollection<T> GetReadOnlyObjectsFromDB<T>() 
    {
        var typeofT = typeof(T);
        if (typeofT.GetType() == typeof(Customer))
        {
            return new ReadOnlyObservableCollection<Customer>
                  (new ObservableCollection<Customer>(dbContext.Customers));
        }
        else if(typeofT.GetType() == typeof(Article))
        {
            return new ReadOnlyObservableCollection<Article>
                  (new ObservableCollection<Article>(dbContext.Articles));
        }
    }

I always get this error:

Cannot implicitly convert type 'System.Collections.ObjectModel.ReadOnlyObservableCollection<Customer>' to 'System.Collections.ObjectModel.ReadOnlyObservableCollection<T>'

and the same for Article. I think its clear what I want with this method but I don't know whats my mistake is...

Thanks for help and happy new year!

like image 984
GrayFox Avatar asked May 01 '26 08:05

GrayFox


2 Answers

Basically, your method isn't generic, and you're not trying to make it generic. Don't hard-code for every possible T, write code that doesn't care what that T is. In this case, assuming you're using Entity Framework, it would look like

public ReadOnlyObservableCollection<T> GetReadOnlyObjectsFromDB<T>()
    where T : class
{
    return new ReadOnlyObservableCollection<T>(dbContext.Set<T>().Local);
}

Other ORMs may have similar functions. Let the dbContext worry about mapping T to the right collection, that's not something you should be worrying about.

Also, new ObservableCollection<T>(o) copies o's items to a new list, it doesn't track any changes in o. Luckily, Entity Framework already provides an ObservableCollection<T>, that does report changes to the entities, that you can use instead.

You do need to state that T must be a reference type, for the simple reason that dbContext.Set<T> requires T to be a reference type.

The approach you're taking is not a good practice, but in order to convince the compiler to do what you want you need to cast your result items to T instead of trying to do it the other way around:

if (typeofT.GetType() == typeof(Customer))
    return new ReadOnlyObservableCollection<T>
              (new ObservableCollection<T>(dbContext.Customers.Cast<T>()));
like image 21
m0sa Avatar answered May 02 '26 20:05

m0sa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!