是否有相当于在F#中创建C#隐式运算符?

wet*_*tes 27 c# f#

在C#中,我可以将隐式运算符添加到类中,如下所示:

public class MyClass
{
    private int data;

    public static implicit operator MyClass(int i)
    {
        return new MyClass { data = i };
    }

    public static implicit operator MyClass(string s)
    {
        int result;

        if (int.TryParse(s, out result))
        {
            return new MyClass { data = result };
        }
        else
        {
            return new MyClass { data = 999 };
        }
    }

    public override string ToString()
    {
        return data.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以传递任何期望MyClass对象为字符串或int的函数.例如

public static string Get(MyClass c)
{
    return c.ToString();
}

static void Main(string[] args)
{
    string s1 = Get(21);
    string s2 = Get("hello");
    string s3 = Get("23");
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在F#中这样做?

kvb*_*kvb 30

正如其他人所指出的那样,F#中没有办法进行隐式转换.但是,您总是可以创建自己的运算符,以便更容易显式转换(并重用现有类已定义的任何op_Implicit定义):

let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

type A() = class end
type B() = static member op_Implicit(a:A) = B()

let myfn (b : B) = "result"

(* apply the implicit conversion to an A using our operator, then call the function *)
myfn (!> A())
Run Code Online (Sandbox Code Playgroud)


Fra*_*sco 8

关于类型安全和类型推断,隐式转换相当成问题,所以答案是:不,它实际上是一个有问题的特性.