Tag: 函数式编程

具有未知数量参数的Func

请考虑以下伪代码: TResult Foo(Func f, params object[] args) { TResult result = f(args); return result; } 该函数接受具有未知数量的generics参数的Func和相应参数的列表。 是否可以用C#编写? 如何定义和调用Foo ? 如何将args传递给f ?

在C#中,在算法中使用递归函数是一种好习惯吗?

在许多使用递归的函数语言中被认为是一种很好的实践。 我认为这很好,因为编译器优化了函数式语言的代码。 但是在创建算法时,在C#中使用递归是一种好习惯吗? 就C#而言,是否正确,递归算法将导致您的堆栈增长非常显着(如果调用量非常大)并且这根本不会快,并且可能导致堆栈溢出。 或者还有一些优化可以使递归函数高效? 如果您在使用函数语言中的递归和C#的算法之间进行一些比较(速度,内存,可读性),我将不胜感激。

为什么C#编译器不能从函数签名推断generics类委托?

我正在使用一个函数,它将两个函数作为参数,并返回一个新的组合函数: public static Action Compose(Action first, Action second) { return new Action(arg => { first(arg); second(); }); } 我注意到编译器抱怨如果我没有指定T ,当发送静态或成员函数时(而不是实际的Action对象): static void Main(string[] args) { // compiler error here var composed = Compose(Test, () => Console.WriteLine(” world”)); composed(“hello”); Console.ReadLine(); } public static void Test(string arg) { Console.Write(arg); } 错误消息: 无法从用法中推断出方法’ConsoleTest.Program.Compose(System.Action,System.Action)’的参数。 尝试显式指定类型参数。 我的问题 :为什么不能在这里推断出类型论证? Test的签名在编译时是已知的,不是吗? 是否真的有一些function可以代替Test […]

为什么Funcs不接受超过16个参数?

由于Javascript是我最熟练的语言,因此我熟悉将函数用作第一类对象。 我原以为C#缺少这个function,但后来我听说Func和Action以及delegate ,我认为这非常棒。 例如,您可以声明一个连接两个字符串的Func ,并在它们之间放置一个空格,如下所示: Func concat = (a,b) => a + ” ” + b; 当你输入时我注意到了 Func< IntelliSense显示它有17个重载: delegate System.Func delegate System.Func delegate System.Func …snip… delegate System.Func 那让我开怀大笑。 我查看了Func的MSDN文档并再次笑了起来。 这让我尝试用17个参数声明一个Func 。 它会导致错误( Using the generic type ‘System.Func’ requires 1 type arguments )。 我同意,拥有一个接受超过16个参数的Func可能不是一个好主意。 即便如此,这似乎是Func实施的一种方式。 它需要记录17个简单的不同重载。 这是它真正需要知道的全部内容:最后一个类型参数是返回类型,并且它之前的所有类型参数都是参数类型。 那么,如果我想创建一个超过16个参数的Func ,我该怎么办? 为什么还有限制? 为什么C#不能让你用任意数量的参数声明一个Func ?

“Uncurrying”.NET中的实例方法

您是否可以创建实例方法的委托而无需在创建时指定实例? 换句话说,你可以创建一个“静态”委托,它应该调用该方法的实例作为它的第一个参数吗? 例如,如何使用reflection构造以下委托? Func = i=>i.ToString(); 我知道我可以使用methodInfo.Invoke,但速度较慢,并且在调用之前不检查类型正确性。 当您拥有特定静态方法的MethodInfo时,可以使用Delegate.CreateDelegate(delegateType, methodInfo)构造委托,并且静态方法的所有参数都保持空闲。 正如Jon Skeet指出的那样,如果方法在引用类型上是非虚拟的,则可以简单地应用相同的方法来创建实例方法的开放委托。 决定在虚拟方法上调用哪个方法很棘手,因此不是那么简单,值类型看起来根本不起作用。 对于值类型, CreateDelegate表现出非常奇怪的行为: var func37 = (Func)(37.ToString); var toStringMethod = typeof(int).GetMethod(“ToString”, BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof(CultureInfo) }, null); var func42 = (Func)Delegate.CreateDelegate(typeof(Func), 42, toStringMethod,true); Console.WriteLine( object.ReferenceEquals(func37.Method,func42.Method)); //true Console.WriteLine(func37.Target);//37 Console.WriteLine(func42.Target);//42 Console.WriteLine(func37(CultureInfo.InvariantCulture));//37 Console.WriteLine(func42(CultureInfo.InvariantCulture));//-201040128… WTF? 如果实例方法属于值类型(这适用于引用类型),则使用null作为目标对象调用CreateDelegate会引发绑定exception。 几年后的一些后续行动:导致func42(CultureInfo.InvariantCulture);的错误绑定目标func42(CultureInfo.InvariantCulture); 在我的示例中返回”-201040128″而不是”42″是内存损坏,可能允许远程代码执行( cve-2010-1898 ); 这是在2010年ms10-060安全更新中修复的。 当前框架正确打印42! 这并没有使回答这个问题变得更容易,但解释了这个例子中特别奇怪的行为。

在函数式编程风格中最好完成哪些任务?

我刚刚发现了函数编程风格,我相信它会减少开发工作,使代码更容易阅读,使软件更易于维护。 然而,问题是我在说服任何人。 好吧,最近我有机会就如何减少软件开发和维护工作发表演讲,我想向他们介绍函数式编程的概念以及它如何使团队受益。 我有这样的想法,即向人们展示两组完全相同的代码,一个以非常强制的方式编码,另一个以非常实用的方式编写,以表明函数式编程可以使代码更简单,更容易理解和因此可维护。 有没有这样的例子,除了Luca Bolognese的着名的正方形例子之外?