1

ジェネリック、つまりTC# での動作について混乱しています。私が間違っていない限り、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++ の用語で言えば、あなたの現在の実装は 3 つの個別のテンプレート関数に似ていますが、私の実装はテンプレート クラスに似ています。

于 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

まず、インターフェースをジェネリックにする必要があります。

public interface IDataGateway<T>

T次に、実装中に指定します。

public class LibraryGateway : IDataGateway<Media>
于 2013-04-23T18:49:32.013 に答える
0

3 つのジェネリック メソッドを使用して非ジェネリック インターフェイスを定義しています。

これらのメソッドのそれぞれはT、 の値がTそれらの間で同じではないため、任意の type を受け入れることができます。

おそらく、3 つの非ジェネリック メソッドを使用してジェネリック インターフェイスを定義するつもりだったのでしょう。

public interface IDataGateway<T>
{
    void InsertRow(T row);
    void UpdateRow(T row);
    IEnumerable<T> GetTable(T table);
}
于 2013-04-23T18:49:45.120 に答える
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 に答える
0

Updaterow のスペルが間違っています。UpdateRow と読む必要があります。

インターフェイスを実装する最も簡単な方法は、インターフェイス名をマウスでクリックし、ctrl+ を押すことです。次に、実装インターフェイスを選択します

于 2013-04-23T19:14:11.083 に答える