【发布时间】:2016-08-01 15:48:50
【问题描述】:
我正在尝试创建一个通用接口,它允许我使用多种方法与数据库进行交互。我希望我的业务应用程序能够实例化任何连接方法并确保接口是相同的。
这是我现在正在尝试的简化版本。
数据库接口,其中IElement 是另一个定义表的接口。
public interface IDatabase
{
void setItem( IElement task ); //this works fine
List<T> listTasks<T>() where T : IElement; // this doesn't
}
IElement 接口:
public interface IElement
{
int id { get; set; }
}
IElement 的实现:
public class TaskElement: IElement
{
public int id { get; set; }
public string name {get; set; }
}
IDatabase 的实现:
public class SQLiteDb: IDatabase
{
public SqLiteDb( SQLiteConnection conn )
{
database = conn;
}
public void setItem( IElement task )
{
// works fine when passed a new TaskElement() which is an implementation of IElement.
database.Insert( task );
}
//it all goes off the rails here
public List<T> listItems<T>() where T : IElement
{
var returnList = new List<IElement>
foreach (var s in database.Table<TaskElement>())
{ returnList.Add(s); }
return returnList;
}
我在这方面尝试了很多变体,但每一个都给了我一个新问题。例如,这里有两个错误。
1)
方法
'SQLiteDb.listTasks<T>()'的类型参数无法从用法中推断出来。尝试明确指定类型参数。
2)
无法将类型
'System.Collections.Generic.List<TaskElement>'隐式转换为'System.Collections.Generic.List<T>'
我尝试将方法更改为使用显式类型,但在那里遇到了问题。如果我使用IElement(我的所有元素的通用接口)我不能返回一个TaskElement对象列表(我的IElement实现),因为它与返回类型(List<IElement>)不匹配,如果我改变List<TaskElement> 的返回类型我不再实现接口。
值得注意的是,如果我停止使用接口和泛型,我可以很容易地让它工作,但这似乎是使用接口的理想情况。当另一个应用程序(如直接继承)可能更好时,也许我正在努力将很多东西塞进一个接口?
问题
如何实现一个具有通用返回值的接口,同时限制可以返回的类型仅用于另一个接口的实现。
【问题讨论】:
-
你试过
var returnList = new List<T>(); -
请注意,在实现接口时查看您的 TaskElement,您必须将 Id 设为公开(默认情况下 c# 将其设置为私有)
-
与您的问题无关,但如果您刚刚开始 c#,您应该阅读coding conventions 其他开发人员会感谢您!
-
你的方法签名是
List<T> listTasks<T>() where T : IElement。这意味着接口的任何实现都应该能够与实现IElement的任何类型一起使用。这是故意的吗? -
也许你需要让接口本身像
public interface IDatabase<T> where T:IElement一样通用?