我没有太多运气寻找这个答案,因为我认为我对它的正确用语知之甚少。
(编辑代码的清晰度以及我如何调用它)
我有一个实例化扩展方法的类:
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;
}
}
我这样称呼这个方法:
DataTable table = SomehowGetTable();
IList<MyObject> list = table.Bar<MyObject>();
再次,大大简化。
现在,我想做的是添加一个委托(?),以便在我获得列表后,我可以在列表中的每个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;
}
}
我不知道我需要能够传递postProcess ..委托,谓词或动作,主要是因为我仍然是Linq挑战。
或者,这可能甚至不可能?
答案 0 :(得分:3)
你想要的是一个动作&lt; T>所以你可以这样做:
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;
}
}
答案 1 :(得分:2)
首先,您需要将Bar
定义为通用,否则将无法编译。
其次,如果您尝试对列表中的每个元素进行操作,则需要传入一个带有T
类型的单个参数的委托,并且不返回任何值。内置的.NET委托类型为Action<T>
,它会很好。
所以,
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;
}
答案 2 :(得分:1)
签名将是
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);
}
现在.Net几乎将所有方法签名带到了Action
和Func
代表可能需要的表格中。虽然action包含所有void返回类型方法,但Func引入了非void返回。
请注意,必须将T定义为方法的类型参数。编译器可能能够从您提供给方法的操作中推断出T:
List<double> myDoubles = table.Bar((double x) => Debug.Writeline(x));
例如,如果您实际处理的是不同类型的值,则签名可能如下所示:
public static IList<Z> Bar<T,Z>(this DataTable table, Func<T,Z> postProcess) {
return /* Get Listof T */ .Select(postProcess).ToList();
}
像
一样使用List<int> values = table.Bar((double d) => (int)d);
答案 3 :(得分:1)
尝试Action<T>
:
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 interface IDo
{
Do();
}
public static class Foo
{
public static IList<T> Bar(this DataTable table) where T : IDo
{
IList<T> list = ... // do something with DataTable.
foreach(T item in list)
{
item.Do();
}
return list;
}
}
答案 4 :(得分:1)
你可以做任何一次
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();
...
}