将Func <t,string =“”>转换为Func <t,bool =“”> </t,> </t,>

时间:2011-08-21 12:13:05

标签: c# func

我认为我的思绪正在爆发,试图弄清楚Funcs ......如果这没有意义,我道歉,现在它对我有意义,但已经过了漫长的一天......

1)假设你有一个func,它接受T并输出一个字符串:

 Func<T, string> 

你能把它变成一个接受T的函数并根据某些逻辑返回一个bool(在这种情况下,如果返回的字符串为空(String.IsNullOrWhiteSpace)?

 Func<T, bool> 

2)如果给你一个

,你能做同样的事吗?
Expression<Func<T, string>>

并需要将其转换为

Func<T, bool>

根据返回的字符串是否为空(String.IsNullOrWhiteSpace)返回true / false?

由于

4 个答案:

答案 0 :(得分:11)

对于第一部分,您甚至可以制作一些“更高”的顺序功能:



Func<A,C> MapFun<A,B,C>(Func<A,B> input, Func<B,C> transf)
{
   return a => transf(input(a));
}

一起使用


Func <T,string> test = ...
var result = MapFun(test, String.IsNullOrWhiteSpace);

(我希望C#类型推断在这里工作)

如果您在Func上将其定义为扩展名,则更容易:


public static class FuncExtension
{
    public static Func<A,C> ComposeWith<A,B,C>(this Func<A,B> input, Func<B,C> f)
    {
         return a => f(input(a));
    }
}

这是一个非常简单的测试:


Func<int, string> test = i => i.ToString();
var result = test.ComposeWith(string.IsNullOrEmpty);

对于第二个:我认为你可以将表达式编译成“真正的”Func,然后使用上面的代码。 see MSDN Docs on Expression.Compile

PS:重命名函数以更好地匹配它的意图(它的功能组合)

答案 1 :(得分:3)

您是否可以将其定义为单独的委托:

Func<T, string> func1 = t => t.ToString();
Func<T, bool> func2 = t => string.IsNullOrEmpty(func1(t));

答案 2 :(得分:2)

对于第一部分,该技术被称为函数组合,即组成2个函数来创建新函数。 在你的情况下,你有一个函数Func<T,String>和另一个类型为Func<string,bool>的函数(如字符串为空或null),使用函数组合你可以组合这两个函数来创建一个{{1}类型的新函数。 1}}

大多数函数式编程语言都已经在其标准库或语言本身中定义了这种函数组合。但是,如果语言支持作为一等值的函数,那么为您的语言创建一个并不困难。

在C#中,您可以使用以下功能来编写功能:

Func<T,Bool>

答案 3 :(得分:2)

To 1:Yes(您还可以参数化bool和string):

Func<T, bool> Compose<T>(Func<T, string> source, Func<string, bool>map)
{
    return x => map(source(x));
}

To 2:是的,但你需要先编译表达式:

Func<T, bool> Compose<T>(Expression<Func<T, string>> source, Func<string, bool> map)
{
    return x => compose(source.Compile(), map)
}

.Compile会将表达式编译为动态CLR方法,您可以使用返回的委托调用该方法。

您可以使用以下代码:

Func<int, string> ts = i => i.ToString();
var result = Compose(ts, string.IsNullOrEmpty);

顺便说一下,在这种情况下你应该写一个更高阶的函数。你在这里(代数)做的是组成幺半群。还记得function composition吗? f . g := f(g(x))就是你在这里做的。

将来源视为g:A->B并将其映射为f:B->C(其中A,B和C为集合),因此f . g的结果为h:A->C。顺便说一下,.运算符通常构建为函数式编程语言,例如Haskell,并且实现与compose函数相同的功能(但语法更清晰)。