2009-04-09 3 views
1

私は以下の拡張メソッドを持っていますので、より一般的なものにしたいと思っています。一般的なタイプの静的関数を呼び出すC#の制限を回避するにはどうすればいいですか?

public static IList<User> ToList(this DataTable table) 
{ 
    IList<User> users = new List<User>(); 

    foreach (DataRow row in table.Rows) 
     users.Add(User.FromDataRow(row)); 

    return users; 
} 

この不満足な制限を回避する方法はありますか?

編集:以下の段落はbollocksですが、私はそれを維持しています答えの一つは、将来の読者に理にかなって:

ユーザーだけでなく、私の他のクラスは、IDataModelを実装しています。 IDataModelには1つの方法、FromDataRow(DataRow row)が必要です。関数のプロトタイプをどこに置いても明らかに役立ちません。

答えて

9

あなたが1つの方法だけを必要とする、おそらくFunc<DataRow, T>

public static IList<T> ToList<T>(this DataTable table, 
     Func<DataRow,T> converter) 
{ 
    IList<T> list = new List<T>(); 

    foreach (DataRow row in table.Rows) 
     list.Add(converter(row)); 

    return list; 
} 

funcが...そして、あなたからユーザーを作成する静的メソッドを使用している、あなたのコード例ではtable.ToList<User>(User.FromDataRow)

+0

例の呼び出しでToListの最初のパラメータを削除できます。 – JaredPar

+0

FuncからT型を推論できるはずです。 – Samuel

+0

@サミュエル、私はメソッドグループが型推論に参加しないと信じています。 – JaredPar

3

を呼び出すと思いますDataRow:

foreach (DataRow row in table.Rows) 
    users.Add(User.FromDataRow(row)); 

ただし、staticメソッドを使用してインターフェイスを実装することはできません。

public interface IDataModel { 
    void FromDataRow(DataRow row); 
} 

、あなたのUserクラスはインスタンスメソッドFromDataRow()ではなく、静的なものがあります:あなたのインターフェースは次のようになりますと仮定すると、

あなたのクラスはパラメータなしのコンストラクタを持っている場合、あなたはこの記述することができます。

public static IList<T> ToList<T>(this DataTable table) 
    where T : IDataModel, new() 
{ 
    IList<T> results = new List<T>(); 

    foreach (DataRow row in table.Rows) 
    { 
     T item = new T(); 
     item.FromDataRow(row); 
     results.Add(item); 
    } 

    return users; 
} 

<T>IDataModel制約がIDataModelを実装するタイプが必要です。
new()<T>の制約では、型にパラメータのないコンストラクタが必要です。

+0

ああ、私はそのインターフェースについてまっすぐ考えていませんでした。間違いを指摘してくれてありがとう。この解決策はかなり腫れて見えます。私は行くべき道を考えなければならないだろう。 FromDataRowは実際には静的メソッドです。 –

関連する問題