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

发布于 2024-10-26 11:50:02 字数 969 浏览 0 评论 0原文

我在寻找这个答案时运气不佳,因为我认为我对它的正确术语了解不够。

(为了清楚代码以及如何调用它而编辑)

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

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 挑战。

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

I'm not having much luck searching for this answer, as I think that I don't know enough about the proper terms for it.

(Edit for clarity of code and how I call it)

I have a class that instantiates an extension method:

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;
    }
}

I call this method like this:

DataTable table = SomehowGetTable();

IList<MyObject> list = table.Bar<MyObject>();

Again, greatly simplified.

Now, what I'd like to do, is add a delegate(?) so that after I get the list, I can call a method on each T in the list, like so:

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;
    }
}

I don't know what I need to be able to pass in postProcess.. a delegate, a Predicate, or an Action, mostly because I'm Linq-challenged still.

Or, maybe this isn't even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终难遇 2024-11-02 11:50:02

你想要的是一个 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;
    }
}

What you want is an Action< T > so you can 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;
    }
}
北方的韩爷 2024-11-02 11:50:02

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

其次,如果您尝试对列表中的每个元素进行操作,则需要传入一个委托,该委托采用 T 类型的单个参数并且不返回任何值。内置的 .NET 委托类型是 Action,它会很好地工作。

所以,

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;
}

First, you need to define Bar as generic, otherwise it won't compile.

Second, if you're trying to operate on each element within the list, you need to pass in a delegate that takes a single parameter of type T and returns no value. A built-in .NET delegate type is Action<T>, and it'll do fine.

So,

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;
}
牵你的手,一向走下去 2024-11-02 11:50:02

签名将是

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 通过 ActionFunc 委托将几乎所有您可能需要的方法签名都带到了表中。虽然 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);

The signature would be

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

These days .Net brings virtually all method signatures to the table that you may ever need through Action and Func delegates. While action covers all void return type methods, Func introduces non-void returns.

Note that T must be defined as type argument on your method. The compiler may be able to infer T from the action you provide into the method:

List<double> myDoubles = table.Bar((double x) => Debug.Writeline(x));

For example if you are actually processing the values coming into a different type, the signature may look like :

public static IList<Z> Bar<T,Z>(this DataTable table, Func<T,Z> postProcess) {
  return /* Get Listof T */ .Select(postProcess).ToList();
}

Used like

List<int> values = table.Bar((double d) => (int)d);
山有枢 2024-11-02 11:50:02

您可以执行以下任一操作

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();
   ...
}

You can do either

public static IList<T> Bar<T>(this DataTable table, Action<T> postProcess)
{
   ...
   postProcess(someT);
   ...
}

or add a generic constraint:

public static IList<T> Bar<T>(this DataTable table)
   where T : IHasPostProcess
{
   ...
   someT.postProcess();
   ...
}
Smile简单爱 2024-11-02 11:50:02

尝试 Action

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;
    }
}

Try 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;
    }
}

Or use an interface so you do not have to pass action: (I prefer this one)

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文