在搞乱了F#之后,有一些非常好的功能,我认为当我必须回到C#时,我将会错过任何关于如何让自己脱离以下内容的线索,或者更好地复制它们的功能:
最后但并非最不重要的是,Erlang启发了Message Processing。
答案 0 :(得分:7)
使用F# to make reusable libraries you can call from C#。
关于F#的一个非常好的事情是它仍然是一种.NET语言。您可以根据需要在CLR中混合和匹配语言......
答案 1 :(得分:2)
我不确定这在多大程度上是一个问题。但是,这里有一些典型的模式,我用它来编码C#中的这些功能结构(其中一些来自我的书,其中有一个source code available)。
受歧视的联盟 - 在C#中实现区分联合并不是一种好方法 - 您唯一能做的就是将它们实现为类层次结构(基类表示DU类型和每个DU案例的派生类)。您还可以将Tag
属性(某些enum
类型)添加到基类,以便更轻松地检查该类所代表的大小写。据我所知,这用于LINQ表达式树(实际上应该是区分联合)。
模式匹配 - 您可能永远不会以完全通用的方式获得此功能(例如,使用嵌套模式),但您可以模拟这样的区分联合的模式匹配(使用{{1} }类型,可以是Option<int>
或Some of int
):
None
不完美,但至少你得到一个相对好的方法从案例中提取价值。
消息传递 - 有Concurrency and Coordination Runtime,它在某些方面也基于消息传递,可以在C#中使用。我敢打赌你也可以使用基于迭代器的技术从C#使用F#邮箱处理器,我在this article中描述了它,也用在Wintellect PowerThreading库中。但是,我认为没有人基于这个想法实现了一个可靠的消息传递库。
总之,您可以在C#中模拟许多功能特性,至少在某种程度上可以使用其他功能而没有任何问题(lambda函数和高阶函数)。但是,如果您需要F#的全部功能,那么您只需要说服您的公司开始使用F#: - )。
答案 2 :(得分:2)
可以在C#中模拟受歧视的联合和模式匹配,尽管类型定义有点冗长(有些想法请参见How can I duplicate the F# discriminated union type in C#?)。这是我在该问题中提出的方法:F#类型type T = ACase of A | BCase of B | CCase of C
可以用C#抽象类表示,并带有一些静态辅助方法。
public abstract class T {
public abstract X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase);
private class ACase : T {
private A a;
public ACase(A a) { this.a = a; }
public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
return aCase(a);
}
}
private class BCase : T {
private B b;
public BCase(B b) { this.b = b; }
public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
return bCase(b);
}
}
private class CCase : T {
private C c;
public CCase(C c) { this.c = c; }
public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
return cCase(c);
}
}
public static T MakeACase(A a) { return new ACase(a); }
public static T MakeBCase(B b) { return new BCase(b); }
public static T MakeCCase(C c) { return new CCase(c); }
}
匹配现在看起来类似于F#,但没有案例标签。相当于这个F#代码:
function
| A a -> 1
| B b -> 2
| C c -> 3
这是C#代码:
public static int MatchDemo(T t) {
return t.Match(
a => 1,
b => 2,
c => 3);
}
答案 3 :(得分:0)