C# 在泛型上调用实例方法的委托

C# 在泛型上调用实例方法的委托,c#,.net,linq,generics,delegates,C#,.net,Linq,Generics,Delegates,我没有太多的运气来寻找这个答案,因为我认为我对它的正确术语了解不够 (为了代码的清晰性和我如何称呼它而进行编辑) 我有一个实例化扩展方法的类: public static class Foo { public static IList<T> Bar<T>(this DataTable table) where T : class, new() { IList<T> list = ... // do something with

我没有太多的运气来寻找这个答案,因为我认为我对它的正确术语了解不够

(为了代码的清晰性和我如何称呼它而进行编辑)

我有一个实例化扩展方法的类:

public static class Foo
{
    public static IList<T> Bar<T>(this DataTable table) where T : class, new()
    {
        IList<T> list = ... // do something with DataTable.

        return list;
    }
}
公共静态类Foo
{
公共静态IList条(此DataTable表),其中T:class,new()
{
IList list=…//对DataTable执行一些操作。
退货清单;
}
}
我这样称呼这个方法:

DataTable table = SomehowGetTable();

IList<MyObject> list = table.Bar<MyObject>();
DataTable=SomehowGetTable();
IList list=table.Bar();
再一次,大大简化了

现在,我想做的是添加一个委托(?),这样在我得到列表后,我就可以对列表中的每个T调用一个方法,如下所示:

public static class Foo
{
    public static IList<T> Bar<T>(this DataTable table, MyDelegate postProcess)
    {
        IList<T> list = ... // do something with DataTable.

        foreach(T item in list)
        {
            t.postProcess();
        }

        return list;
    }
}
公共静态类Foo
{
公共静态IList条(此DataTable表,MyDelegate后处理)
{
IList list=…//对DataTable执行一些操作。
foreach(列表中的T项)
{
t、 后处理();
}
退货清单;
}
}
我不知道我需要什么才能通过后处理。。委托、谓词或动作,主要是因为我仍然受到Linq的挑战

或者,也许这根本不可能?签名可能是

public static IList<T> Bar<T>(this DataTable table, Action<T> postProcess) {
  var list = // Get ILIst<T> from DataTable
  foreach (var i in list)
  postProcess(i);
}
例如,如果您实际正在处理不同类型的值,则签名可能如下所示:

public static IList<Z> Bar<T,Z>(this DataTable table, Func<T,Z> postProcess) {
  return /* Get Listof T */ .Select(postProcess).ToList();
}
公共静态IList条(此数据表,Func后处理){
return/*Get list of T*/.Select(postProcess.ToList();
}

List<int> values = table.Bar((double d) => (int)d);
列表值=table.Bar((双d)=>(int)d);
尝试
操作

公共静态类Foo
{
公共静态IList条(此数据表,操作后处理)
{
IList list=…//对DataTable执行一些操作。
foreach(列表中的T项)
{
后处理(项目);
}
退货清单;
}
}
或者使用界面,这样就不必传递操作:(我更喜欢这个)

公共接口IDo
{ 
Do();
}
公共静态类Foo
{
公共静态IList条(此数据表),其中T:IDo
{
IList list=…//对DataTable执行一些操作。
foreach(列表中的T项)
{
item.Do();
}
退货清单;
}
}

您需要的是一个动作,因此您可以执行以下操作:

public static class Foo
{
    public static IList<T> Bar(this DataTable table, Action<T> postProcess)
    {
        IList<T> list = ... // do something with DataTable.

        foreach(T item in list)
        {
            postProcess(item);
        }

        return list;
    }
}
公共静态类Foo
{
公共静态IList条(此数据表,操作后处理)
{
IList list=…//对DataTable执行一些操作。
foreach(列表中的T项)
{
后处理(项目);
}
退货清单;
}
}
您可以选择

public static IList<T> Bar<T>(this DataTable table, Action<T> postProcess)
{
   ...
   postProcess(someT);
   ...
}
公共静态IList条(此数据表,操作后处理)
{
...
后处理(someT);
...
}
或添加常规约束:

public static IList<T> Bar<T>(this DataTable table)
   where T : IHasPostProcess
{
   ...
   someT.postProcess();
   ...
}
公共静态IList条(此数据表)
其中T:ihaPostProcess
{
...
someT.postProcess();
...
}

首先,您需要将
Bar
定义为泛型,否则它将无法编译

其次,如果试图对列表中的每个元素进行操作,则需要传入一个委托,该委托接受类型为
T
的单个参数,并且不返回任何值。内置的.NET委托类型是
Action
,这样就可以了

所以

公共静态IList条(此数据表,操作后处理)
{
IList list=…//对DataTable执行一些操作
foreach(列表中的T项)
{
后处理(项目);
}
退货清单;
}

您的第一个示例也不起作用,是吗?无法从
DataTable
推断
T
Bar
也没有定义为泛型,
T
也没有定义在其他任何地方(当然,假设没有名为
T
的实际类型),我大大减少了我实际拥有的代码,无意中遗漏了一些东西,因为我急着把这个问题贴出来,让它发挥作用。第一个样本在我的世界里确实有效。。。我看看能不能把它修改得更有意义。亨克和亚当,我刚意识到你在说什么。现在编辑这一点…我想你的意思是
T:ihaPostProcess
我接受这一点,因为根据stackoverflow,这是技术上的第一次,也是为了提供一个调用它的示例。这正是我想要的。T是IList中项目的通用类型。我理解得不对吗?列表是返回类型。见亚当的答案。
public static class Foo
{
    public static IList<T> Bar(this DataTable table, Action<T> postProcess)
    {
        IList<T> list = ... // do something with DataTable.

        foreach(T item in list)
        {
            postProcess(item);
        }

        return list;
    }
}
public static IList<T> Bar<T>(this DataTable table, Action<T> postProcess)
{
   ...
   postProcess(someT);
   ...
}
public static IList<T> Bar<T>(this DataTable table)
   where T : IHasPostProcess
{
   ...
   someT.postProcess();
   ...
}
public static IList<T> Bar<T>(this DataTable table, Action<T> postProcess)
{
    IList<T> list = ... // do something with DataTable

    foreach(T item in list)
    {
        postProcess(item);
    }

    return list;
}