函数式C#API设计(返回函数参数并添加计算结果)
在C#代码中使用函数式编程技术有一个问题。范例 让我们有一个接口函数式C#API设计(返回函数参数并添加计算结果),c#,functional-programming,method-chaining,C#,Functional Programming,Method Chaining,在C#代码中使用函数式编程技术有一个问题。范例 让我们有一个接口 interface IGraph { /*contains vertices and edges*/} 假设我们需要布局图的顶点(为每个顶点指定点) 简单布局路线可具有以下特征: ILayoutInfo SimpleLayout(IGraph graph); 哪一个可以这样使用 void Demo() { IGraph graph = CreateGraphInAnyWay(); ILayoutInfo layout
interface IGraph { /*contains vertices and edges*/}
假设我们需要布局图的顶点(为每个顶点指定点)
简单布局路线可具有以下特征:
ILayoutInfo SimpleLayout(IGraph graph);
哪一个可以这样使用
void Demo() {
IGraph graph = CreateGraphInAnyWay();
ILayoutInfo layout = SimpleLayout(graph);
PrintCoordinates(graph,layout);
}
在下面的设计中,打印坐标需要同时参考图形和布局
考虑功能样式设计,其中布局路由增加了图形信息
包含有关图形顶点协调的信息
ILayoutedGraph SimpleLayoutNew(IGraph graph);
其中ILayoutedGraph同时实现IGraph和ILayoutInfo
void DemoNew() {
IGraph graph = CreateGraphInAnyWay();
ILayoutedGraph layoutedGraph = SimpleLayoutNew(graph);
PrintCoordinatesNew(layoutedGraph);
}
1) 在本设计中,PrintCoordinatesNew仅获取一个参数。
2) 奇怪的界面ILayoutedGraph诞生了,它不包含任何方法,只是
包装其他接口。如果某个库有其他类型,比如INetwork,那么我们最终会失败
创建包装接口ILayoutedNetwork、ILayoutedTree(这是错误的)
所以这样的技术只在函数语言中使用,只是因为它们不能以其他方式工作(并没有状态,所以函数必须将输入和计算信息结合起来,以供外部例程使用),或者它在命令式语言中也是可行的
非常感谢
PS:在这里可以找到一个更详细的漂亮打印示例
能否使用一个同时实现接口和将返回转换为该类的类来实现此功能?的原始API没有问题
void Demo() {
IGraph graph = CreateGraphInAnyWay();
ILayoutInfo layout = SimpleLayout(graph);
PrintCoordinates(graph,layout);
}
它功能完善。命令式API在创建后将涉及对图形的更改。乙二醇
void Demo() {
IGraph graph = CreateGraphInAnyWay();
graph.Layout(new SimpleLayout()); // changes the state of graph
PrintCoordinates(graph);
}
至于ILayoutedGraph、ILayoutedTree、ILayoutedQueue等的问题,我认为您可以通过函数式语言中的泛型类和允许的OO语言中的多重继承来解决这个问题
就我个人而言,我建议使用泛型:ILayout
其中a
是一种需要布置边缘的东西。如果传递两个参数时让您感到不安的是布局(ILayoutInfo)链接到用于生成它的图形。我将毫无意义地传递一个布局和一个不用于生成它的图形
在这种情况下,您可以在布局信息中保留对图形的引用,并在ILayoutInfo接口上提供访问器
这样,您只能传递ILayoutInfo实例,并且PrintCoordinates函数仍然可以访问用于生成ILayoutInfo的图形
如果您有其他类型的对象可以生成布局信息,请为它们使用公共接口,或使ILayoutInfo通用。问题在于要发布的API(接口):传统样式案例1)IGraph、ILayoutInfo和SimpleLayout(IGraph):ILayoutInfo或功能样式案例2)IGraph、ILayoutedGraph SimpleLayoutNew(IGraph):ILayoutedGraph===ILayoutedGraph确实可以由某些内部类实现。谢谢。你真的给了我一口新鲜空气。
void Demo() {
IGraph graph = CreateGraphInAnyWay();
graph.Layout(new SimpleLayout()); // changes the state of graph
PrintCoordinates(graph);
}