GrayFox
GrayFox

Reputation: 1089

Cannot implicitly convert type error in generic method

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!

Upvotes: 3

Views: 630

Answers (2)

m0sa
m0sa

Reputation: 10940

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>()));

Upvotes: 1

user743382
user743382

Reputation:

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.

Upvotes: 8

Related Questions