1

我对泛型如何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() { }
}

我不知道会传递什么类型,这就是我尝试使用泛型的原因。

4

7 回答 7

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相同。每个方法都由其自己的类型参数泛型化,但包含的接口类型本身不是泛型的。UV

通过在类型本身上声明类型参数,您可以将方法的类型参数限制为在由子类实现时相同。在您似乎熟悉的 C++ 术语中,您当前的实现类似于三个单独的模板函数,而我的实现更类似于模板类。

于 2013-04-23T18:49:09.753 回答
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专门对 type 的项目进行操作Media。的其他实现IDataGateway<T>可以对其他类型进行操作,但LibraryGateway仅对Media对象进行操作。

于 2013-04-23T18:48:57.617 回答
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() { }
}

...我认为这应该可以满足您的需求。

于 2013-04-23T18:51:50.863 回答
0

您正在使用三个泛型方法定义一个非泛型接口。

这些方法中的每一个都具有接受任何类型的能力T,因为它们之间的值T不一样。

您可能打算做的是用三个非泛型方法定义一个泛型接口。

public interface IDataGateway<T>
{
    void InsertRow(T row);
    void UpdateRow(T row);
    IEnumerable<T> GetTable(T table);
}
于 2013-04-23T18:49:45.120 回答
0

你错过了拼写 Updaterow,它应该是 UpdateRow。

实现接口的简单方法是,用鼠标点击接口名称,按 ctrl+。然后选择实现接口

于 2013-04-23T19:14:11.083 回答
0

首先,您必须使您的界面通用:

public interface IDataGateway<T>

然后T在实现时指定:

public class LibraryGateway : IDataGateway<Media>
于 2013-04-23T18:49:32.013 回答
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>
{

}
于 2013-04-23T18:59:33.490 回答