简体   繁体   English

反正有使用F#中的C#隐式运算符吗?

[英]Is there anyway to use C# implicit operators from F#?

If I have a C# class with implicit conversion to double, like so: 如果我有一个将隐式转换为double的C#类,如下所示:

public class Parameter
{
    private double _value;
    public Parameter(double value) { _value = value }
    public static implicit operator double(Parameter p) { return _value; }
}

F# doesn't like me trying to use it as if it were a float : F#不喜欢我尝试像使用float那样使用它:

let a = Parameter(4.0)
let b = Parameter(2.0)
let c = a * Math.Sin(b) <-- 'expected float, here Parameter'

Is there any way to do this (I'm guessing there isn't, based on this question/answer ), and if not, what would be a decent workaround? 有什么方法可以做到这一点(基于这个问题/答案 ,我猜没有),如果没有,什么是不错的解决方法?

F# does not perform implicit conversions, but it allows you to define an explicit operator to run them. F#不会执行隐式转换,但是它允许您定义一个显式运算符来运行它们。 See the kvb's answer to a previous question : 请参阅kvb对先前问题的回答

let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x) 

This is using statically resolved type parameters to say that either the input or the result needs to provide implicit conversion operator - these are compiled to methods named op_Implicit , so the F# compiler checks for a static method with this special name. 这是使用静态解析的类型参数来表示输入或结果需要提供隐式转换运算符-它们被编译为名为op_Implicit方法,因此F#编译器将使用此特殊名称检查静态方法。

Using the !> operator, you can now explicitly say where you want to convert Parameter to a float (two times) in your code sample like this: 现在,使用!>运算符,您可以在代码示例中明确说明要将Parameter转换为float (两次),如下所示:

let a = Parameter(4.0) 
let b = Parameter(2.0) 
let c = !> a * Math.Sin(!> b)

I think the main reason for not allowing implicit conversions in F# is that it would make the type inference a bit more difficult and it would be hard for the compiler to give good error messages. 我认为不允许在F#中进行隐式转换的主要原因是,这会使类型推断变得更加困难,并且编译器将很难给出良好的错误消息。

It won't let you do implicit conversions. 它不会让您进行隐式转换。 Make your conversions explicit where you need to. 使您的转换明确在需要的地方。

See here for various ways to do it explicitly: http://natehoellein.blogspot.com/2008/02/basic-type-conversions-with-f.html 请参阅此处以了解各种明确执行此操作的方法: http : //natehoellein.blogspot.com/2008/02/basic-type-conversions-with-f.html

FSharp.Interop.Dynamic uses the DLR, so for most people probably overkill, but has a function Dyn.implicitConvert for dynamically using the C# implicit operator. FSharp.Interop.Dynamic使用DLR,因此对于大多数人来说可能Dyn.implicitConvert过头了,但是它具有Dyn.implicitConvert函数,用于动态使用C#隐式运算符。

   [<Test>] member basic.``Test Implicit Conversion`` ()=
                    let ele = 50
                    ele |> Dyn.implicitConvert |> should equal (decimal 50)

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

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