[英]Pass C# interfaces/classes to F#
I have an existing project written in C#. 我有一个用C#编写的现有项目。 I would like to move part of its business logic to F#.
我想将其部分业务逻辑移至F#。 MyObjectX is a C# class that runs scientific algorithms.
MyObjectX是一个运行科学算法的C#类。 For MyObjectX to run it needs to implement a couple of interfaces, and some dependencies that are injected via methods (not constructor).
要运行MyObjectX,需要实现几个接口,以及通过方法(而不是构造函数)注入的一些依赖项。 Example:
例:
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);
//...
}
}
So now I would like to implement MyObjectX in F#. 所以现在我想在F#中实现MyObjectX。 What is the best way to do that so i can be as functional as possible in my code?
最好的方法是什么,这样我才能在我的代码中尽可能地发挥作用?
Make the existing C# MyObjectX behave as a wrapper/facade between the rest of C# classes and the F# library were the algorithms are implemented in F# modules. 使现有的C#MyObjectX表现为其余C#类之间的包装/外观,而F#库的算法是在F#模块中实现的。
Write a F# class of MyObjectX class that implements the interfaces, and probably call other F# modules. 编写实现接口的MyObjectX类的F#类,并可能调用其他F#模块。
Or non of them. 或者不属于他们。 please advise.
请指教。
Also what is the best way to pass the dependencies of C# to F# like 'IResultProvider/ISignalProvider'? 另外,将C#的依赖关系传递给F#的最佳方法是什么,如'IResultProvider / ISignalProvider'? Do i need to use mutable variables that will get populated with the dependencies via functions in F#?
我是否需要使用可变变量,这些变量将通过F#中的函数填充依赖项?
Please advise. 请指教。 if you can share a code sample i would be thankful.
如果你可以分享代码样本,我会很感激。
I think you could choose between 1 and 2. These are certainly the two most reasonable approaches. 我想你可以在1和2之间做出选择。这些肯定是两种最合理的方法。
I think that the option 2 might be better, because the F# implementation can then stay in simple F# modules using the most idiomatic F# style (such as passing functions around as arguments). 我认为选项2可能更好,因为F#实现可以使用最惯用的F#样式(例如将函数作为参数传递)保留在简单的F#模块中。 The idiomatic F# code is not always easy to use from C#, so if you wrap it in an F# class that implements the required C# interfaces, you are hiding the "F# details" from the C# code, which is good.
惯用的F#代码并不总是很容易在C#中使用,所以如果你将它包装在一个实现所需C#接口的F#类中,你就会隐藏C#代码中的“F#细节”,这很好。
Have a look at: 看一下:
F# Component Design Guidelines which says more things about how to design F# components in a way that makes them easy to use from C#. F#组件设计指南 ,其中介绍了如何以易于使用C#的方式设计F#组件的更多内容。
Interfaces (F#) on MSDN and Interfaces page at F# for Fun and Profit for more details about how to actually write such interface implementation in F#. 有关如何在F#中实际编写此类接口实现的更多详细信息,请参阅MSDN上的接口(F#)和F#上的接口页面以获取Fun和Profit。
FWIW, the (more or less) direct translation of MyObjectX
is 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
although I had to guess at a couple of the interface definitions. 虽然我不得不猜测几个接口定义。
However, this isn't particularly functional . 但是, 这不是特别有用 。 For more information about moving from an object-oriented to a functional mindset, see
有关从面向对象转变为功能性思维模式的更多信息,请参阅
So long as the interface is defined in an assembly referenced by the F# project you can just implement MyObjectX
directly 只要接口在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 =
...
Take a look at the F# documentation. 看一下F#文档。 It is possible to create .NET classes and interfaces trivially and to use those within the language.
可以简单地创建.NET类和接口,并在语言中使用它们。
If you are looking to use IoC, you should have no problem injecting an F# implementation into a C# module and vice versa. 如果您希望使用IoC,那么将F#实现注入C#模块应该没有问题,反之亦然。 Just have a play!
玩一玩!
I'd say go for ( 1 ). 我会说( 1 )。
That way, you'll have make your life easier referencing F# from other F# code, and the wrapper should be trivial to write. 这样,你可以让你的生活更容易从其他F#代码引用F#,并且包装应该是无关紧要的。 That will aslo add a level of indirection, letting you change the C# interface or the F# code without affecting the other side of the system.
这将增加一个间接级别,让您更改C#接口或F#代码,而不会影响系统的另一面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.