2009-11-06 49 views
24

在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(); 
    } 
} 

然後我可以傳遞期待一個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"); 
} 

是否有F#這樣的方式?

回答

27

正如其他人指出的那樣,F#中沒有辦法做隱式轉換。但是,你總是可以創建自己的運營商,使其更容易一點明確轉換的事情(和重用現有的類定義的任何op_Implicit定義):

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

然後你可以使用它像這樣:

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()) 
+0

這似乎是F#2.0中的無效前綴運算符名稱。運營商名稱的規則是否定義在某個地方?我沒有在[MSDN](http://msdn.microsoft.com/zh-cn/library/dd233204.aspx)頁面上看到任何指示此限制的內容。 – Daniel 2011-02-17 20:08:26

+0

從名稱中省略'〜'似乎有效。規則改變了嗎? – Daniel 2011-02-17 20:18:06

+0

@丹尼爾 - 是的,我認爲規則必須改變。省略'〜'不會起作用,因爲它會使它成爲中綴而不是前綴運算符。但是,用'!'替換'〜'應該可以。 – kvb 2011-02-17 21:58:04

8

隱式轉換在類型安全性和類型推斷方面相當麻煩,所以答案是:不,它實際上是一個有問題的功能。

相關問題