繁体   English   中英

将C#接口/类传递给F#

[英]Pass C# interfaces/classes to F#

我有一个用C#编写的现有项目。 我想将其部分业务逻辑移至F#。 MyObjectX是一个运行科学算法的C#类。 要运行MyObjectX,需要实现几个接口,以及通过方法(而不是构造函数)注入的一些依赖项。 例:

public class MyObjectX(): IMathSolver, IBusinessSolver
{
    //private fields
    private int operationMode;
    private ISignalProvider signal;

    //Inject dependcy via method
    public void SetSignalProvider(ISignalProvider signal)
    {
        this.signal = signal;
    }

    //implemention of above interfaces
    public double MethodMathSolver()
    {
        this.signal.GetThreshold();
        //...
    }

    public double Method1BusinessSolver()
    {
    }

    public double Method2MathSolver(IResultProvider provider)
    {
        var x = provider.GetValueAtTime(0.1);
        //...
    }
}

所以现在我想在F#中实现MyObjectX。 最好的方法是什么,这样我才能在我的代码中尽可能地发挥作用?

  1. 使现有的C#MyObjectX表现为其余C#类之间的包装/外观,而F#库的算法是在F#模块中实现的。

  2. 编写实现接口的MyObjectX类的F#类,并可能调用其他F#模块。

  3. 或者不属于他们。 请指教。

另外,将C#的依赖关系传递给F#的最佳方法是什么,如'IResultProvider / ISignalProvider'? 我是否需要使用可变变量,这些变量将通过F#中的函数填充依赖项?

请指教。 如果你可以分享代码样本,我会很感激。

我想你可以在1和2之间做出选择。这些肯定是两种最合理的方法。

我认为选项2可能更好,因为F#实现可以使用最惯用的F#样式(例如将函数作为参数传递)保留在简单的F#模块中。 惯用的F#代码并不总是很容易在C#中使用,所以如果你将它包装在一个实现所需C#接口的F#类中,你就会隐藏C#代码中的“F#细节”,这很好。

看一下:

  • F#组件设计指南 ,其中介绍了如何以易于使用C#的方式设计F#组件的更多内容。

  • 有关如何在F#中实际编写此类接口实现的更多详细信息,请参阅MSDN上的接口(F#)F#上的接口页面以获取Fun和Profit。

FWIW, MyObjectX的(或多或少)直接翻译是

type MyObjectX() =
    let mutable operationMode = 0
    let mutable sp : ISignalProvider = Unchecked.defaultof<ISignalProvider>

    member this.SetSignalProvider signal = sp <- signal

    interface IMathSolver with
        member this.MethodMathSolver () = 
            sp.GetThreshold()
            //
            0.0
        member this.Method2MathSolver provider =
            let x = provider.GetValueAtTime 0.1
            //
            x

    interface IBusinessSolver with
        member this.Method1BusinessSolver () = 0.0

虽然我不得不猜测几个接口定义。

但是, 这不是特别有用 有关从面向对象转变为功能性思维模式的更多信息,请参阅

只要接口在F#项目引用的程序集中定义,您就可以直接实现MyObjectX

type MyObjectX(signal : ISignalProvider) = 
   let mutable operationMode : int = 0;   // assuming this changes

   interface IMathSolver with 
       member x.GetMethodMathSolver() : double =
          signal.GetThreshold()
          // ... 
       member x.MethodBusinessSolver() : double = 
          ... 

看一下F#文档。 可以简单地创建.NET类和接口,并在语言中使用它们。

如果您希望使用IoC,那么将F#实现注入C#模块应该没有问题,反之亦然。 玩一玩!

我会说( 1 )。

这样,你可以让你的生活更容易从其他F#代码引用F#,并且包装应该是无关紧要的。 这将增加一个间接级别,让您更改C#接口或F#代码,而不会影响系统的另一面。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM