我的通用方法存在问题:
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>'
和文章相同。我认为用这种方法清楚我想要什么,但我不知道我的错误是什么......
感谢您的帮助和新年快乐!
答案 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>()));