C#接口和泛型

时间:2013-04-23 18:46:39

标签: .net generics interface

我对于泛型,即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() { }
}

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

7 个答案:

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

也就是说,TUV不相同。每个方法都由其自己的类型参数进行通用化,但包含的接口类型本身并不是通用的。

通过在类型本身上声明类型参数,可以在子类实现时将方法的类型参数限制为相同。在您似乎熟悉的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 +。然后选择实现接口