在具有不同类型参数的 Func 之间进行转换

发布于 2024-10-28 19:29:18 字数 914 浏览 0 评论 0原文

是否有用于在各种类型的 Func 委托之间进行转换的内置方法?也就是说,假设您需要一个 Func,但您有一个 Func(并且您有应该为 T 参数传入的值)。例如:

static TREsult Foo<TResult>(Func<TResult> f)
{
   // ...
   TResult result = f();
   // ...
   return result;
}

static int MyFunc(int i)
{
    return i;
}

void CallFoo()
{
    Func<int> func = ConvertFunc(MyFunc, 1); // Does this family of methods exist?
    int j = Foo(func);
}

我自己写了这样的:

    static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
    {
        return () => f1(t);
    }

    static Func<TResult> ConvertFunc<T1, T2, TResult>(Func<T1, T2, TResult> f2, T1 t1, T2 t2)
    {
        return () => f2(t1, t2);
    }

    // etc.

但我想知道是否存在这样的一系列方法(或者即使有更好的方法来做到这一点)。

本质上,我这样做是为了在方法中有一些样板代码,然后是函数调用(其中函数中的数量和类型会有所不同,但返回类型相同),然后是更多样板代码车牌代码。

欢迎大家提出意见!谢谢。

Are there built in methods for converting between the various types of Func delegates? That is, suppose you need a Func, but you have a Func (and you have the value that should be passed in for the T parameter). For example:

static TREsult Foo<TResult>(Func<TResult> f)
{
   // ...
   TResult result = f();
   // ...
   return result;
}

static int MyFunc(int i)
{
    return i;
}

void CallFoo()
{
    Func<int> func = ConvertFunc(MyFunc, 1); // Does this family of methods exist?
    int j = Foo(func);
}

I've written my own, like this:

    static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
    {
        return () => f1(t);
    }

    static Func<TResult> ConvertFunc<T1, T2, TResult>(Func<T1, T2, TResult> f2, T1 t1, T2 t2)
    {
        return () => f2(t1, t2);
    }

    // etc.

But I'm wondering if a family of methods like this exists (or even if there's a better way to do this).

Essentially, I'm doing this for a case where there is some boiler plate code in a method followed by a function call (where the number and types in the function will vary, but the return type is the same), followed by more boiler plate code.

All opinions welcome! Thanks.

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

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

发布评论

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

评论(1

樱&纷飞 2024-11-04 19:29:18
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
    return () => f1(t);
}

对我来说,这种代码看起来有点危险 - 本身并不是什么问题,但需要小心。您正在使用闭包将输入变量嵌入到函数中。但这可能会导致严重的错误,因为如果变量在转换 Func 和运行它之间发生变化,结果就会不同。

我只是好奇这样做有什么好处。您是否试图向函数的使用者隐藏输入参数?只要变量是传递给它的本地变量,就可以了。

就解决方案而言,不会有一个解决方案,因为 .NET 出于同样的原因创建了 16 个不同的通用 Func

您也许可以使用反射来实现解决方案,但您将为调用函数付出代价。 MethodInfo.GetGenericArguments() 将为您提供类型,然后您可以使用 MethodInfo.MakeGenericMethod() 创建新类型。


更新

只是为了说明我的观点:

    static int Double(int number)
    {
        return number * 2;
    }

    static void Main(string[] args)
    {

        int i = 2;
        Func<int> f = () => Double(i);
        i = 3;
        Console.WriteLine(f()); // prints 6 and not 4

    }
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
    return () => f1(t);
}

This kind of code to me looks a bit dangerous - not that by itself is anything wrong but need to be careful. You are using closure to embed an input variable in the function. But this could lead to difficult bugs since if the variable changes between converting Func and running it, the result would be different.

I am just curious what would be the benefit. Are you trying to hide away input parameter from the consumer of the function? As long as the variable is a local one passed to it, would be fine.

In terms of a solution, there would not be one since .NET has created 16 different generic Func<> exactly for the same reason.

You can perhaps use reflection to implement a solution but you would be paying a penalty for calling the functions. MethodInfo.GetGenericArguments() would give you the types and you then can use MethodInfo.MakeGenericMethod() to create new ones.


Update

Just to illustrate my point:

    static int Double(int number)
    {
        return number * 2;
    }

    static void Main(string[] args)
    {

        int i = 2;
        Func<int> f = () => Double(i);
        i = 3;
        Console.WriteLine(f()); // prints 6 and not 4

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