不能在泛型方法中隐式转换类型错误

时间:2014-12-28 16:17:39

标签: c# generics

我的通用方法存在问题:

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

我总是收到这个错误:

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

和文章相同。我认为用这种方法清楚我想要什么,但我不知道我的错误是什么......

感谢您的帮助和新年快乐!

2 个答案:

答案 0 :(得分:7)

基本上,您的方法不是通用的,并且您并不是想让它变得通用。不要为每个可能的T硬编码,编写不关心T内容的代码。在这种情况下,假设您正在使用实体框架,它看起来像

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

其他ORM可能具有类似的功能。让dbContext担心将T映射到正确的集合,这不是您应该担心的事情。

此外,new ObservableCollection<T>(o)o个项目复制到新列表,它不会跟踪o中的任何更改。幸运的是,实体框架已经提供了ObservableCollection<T>,它确实报告了对实体的更改,您可以使用它们。

您需要声明T必须是引用类型,原因很简单dbContext.Set<T>需要T作为引用类型。

答案 1 :(得分:1)

您采取的方法不是一个好习惯,但为了说服编译器执行您想要的操作,您需要将结果项投射到T而不是尝试以相反的方式执行此操作:< / p>

if (typeofT.GetType() == typeof(Customer))
    return new ReadOnlyObservableCollection<T>
              (new ObservableCollection<T>(dbContext.Customers.Cast<T>()));