我对于泛型,即T
如何在C#中工作感到困惑。它似乎与C ++的行为方式不同,除非我弄错了。我正在尝试为数据网关创建一个简单的界面:
编辑已更新以匹配答案。 Visual Studio现在抱怨派生类没有实现接口方法。
public interface IDataGateway<T>
{
void InsertRow(T row);
void UpdateRow(T row);
IEnumerable<T> GetTable();
}
public class LibraryGateway : IDataGateway<Media>
{
public void InsertRow(Media item) { }
public void Updaterow(Media item) { }
public IEnumerable<Media> GetTable() { }
}
我不知道会传递什么类型,这就是我尝试使用泛型的原因。
答案 0 :(得分:2)
您正在单独声明每个方法的类型参数。您应该在接口类型本身上声明它。
public interface IDataGateway<T>
{
void InsertRow(T row);
void UpdateRow(T row);
IEnumerable<T> GetTable(T table);
}
public class LibraryGateway : IDataGateway<Media>
{
public void InsertRow(Media item) { }
public void Updaterow(Media item) { }
public IEnumerable<Media> GetTable() { }
}
为了澄清,您当前的实施可以改写为:
public interface IDataGateway
{
void InsertRow<T>(T row);
void UpdateRow<U>(U row);
IEnumerable<V> GetTable(V table);
}
也就是说,T
与U
和V
不相同。每个方法都由其自己的类型参数进行通用化,但包含的接口类型本身并不是通用的。
通过在类型本身上声明类型参数,可以在子类实现时将方法的类型参数限制为相同。在您似乎熟悉的C ++术语中,您当前的实现类似于三个单独的模板函数,而我的实现更类似于模板类。
答案 1 :(得分:1)
看起来您正在尝试创建和实现通用接口,而不是通用方法。
public interface IDataGateway<T>
{
void InsertRow(T row);
void UpdateRow(T row);
IEnumerable<T> GetTable(T table);
}
public class LibraryGateway : IDataGateway<Media>
{
public void InsertRow(Media item) { }
public void Updaterow(Media item) { }
public IEnumerable<Media> GetTable(Media table) { }
}
当你有一个泛型方法时(如在原始问题中),这意味着可以使用任何类型的参数调用单个实现(例如LibraryGateway.InsertRow
) - 仅在运行时知道。但是,在实现通用接口时,可以参数化接口,以便LibraryGateway.InsertRow
专门对类型为Media
的项进行操作。 IDataGateway<T>
的其他实现可能适用于其他类型,但LibraryGateway
仅适用于Media
个对象。
答案 2 :(得分:1)
从您的示例中,我认为最有效的方法是使接口本身具有通用性,而不是其中的方法:
public interface IDataGateway<T>
{
void InsertRow(T row);
void UpdateRow(T row);
IEnumerable<T> GetTable(T table); // ???
}
我认为你的GetTable()
方法也需要修复 - 如果T
是表中包含的对象的类型,那么它(可能!)也不是表的类型。也许你的意思是IEnumerable<T> GetTable();
?
然后你可以这样做:
public class LibraryGateway : IDataGateway<Media>
{
public void InsertRow(Media item) { }
public void UpdateRow(Media item) { }
public IEnumerable<Media> GetTable() { }
}
......我认为应该做你正在寻找的事情。
答案 3 :(得分:0)
首先,您必须使您的界面具有通用性:
public interface IDataGateway<T>
然后在实施时指定T
:
public class LibraryGateway : IDataGateway<Media>
答案 4 :(得分:0)
您正在使用三种通用方法定义非泛型接口。
这些方法中的每一种都能够接受任何类型T
,因为它们之间的T
值不相同。
您可能要做的是使用三种非泛型方法定义通用接口。
public interface IDataGateway<T>
{
void InsertRow(T row);
void UpdateRow(T row);
IEnumerable<T> GetTable(T table);
}
答案 5 :(得分:0)
或许这样吗?
public interface IDataGateway<T>
{
void InsertRow(T row);
void UpdateRow(T row);
IEnumerable<T> GetTable(T table);
}
public abstract class LibraryGateway<T>
{
public void InsertRow(T item) { }
public void Updaterow(T item) { }
public IEnumerable<T> GetTable<T>() { }
}
public class MediaLibraryGateway : GateWay<Media>, IDataGateway<Media>
{
}
答案 6 :(得分:0)
你错过拼写的Updaterow,它应该读取UpdateRow。
Easiets实现界面的方法是,用鼠标点击界面名称,点击ctrl +。然后选择实现接口