簡體   English   中英

可以將C#擴展方法添加到F#類型中嗎?

[英]Can a C# extension method be added to an F# type?

我有一個人的F#庫,里面有一個類型:

module HisModule

type hisType {
    a : float;
    b : float;
    c : float;
}

我在C#中使用它,我想為它添加一個“ToString()”方法,以便於調試。

但以下似乎不起作用:

public static class MyExtensions
{
    public static string ToString(this HisModule.hisType h)
    {
        return String.Format("a={0},b={1},c={2}", h.a, h.b, h.c);
    }
}
....
var h = new hisType();
Console.WriteLine(h.ToString());  // prints "HisModule+hisType"

任何想法為什么不呢?

正如其他人所指出的,對象上的ToString總是比你的擴展方法更好的匹配。 您應該更改擴展方法的簽名; 更改名稱可能是正確的方法。

而且:你說這個東西的目的是為了方便調試。 重寫ToString可能是錯誤的做法; ToString可能用於除調試之外的其他內容。 我傾向於制作我自己特別命名的方法,其名稱清楚地反映了該方法的目的。

如果要創建新類型並希望在調試器中具有特殊的顯示行為,則最簡單的方法是使用調試器顯示屬性

如果您想真正想要以有趣的方式顯示復雜的數據結構,請考慮編寫一個Debugger Visualizer

你的問題的答案是“是”。 但是,您的示例不成功,因為方法解析在找到object.ToString()時成功,因此編譯器永遠不會查找擴展方法。 嘗試使用其他名稱:

public static class MyExtensions 
{ 
    public static string Foo(this HisModule.hisType h) 
    { 
        return String.Format("a={0},b={1},c={2}", h.a, h.b, h.c); 
    } 
} 

....   
var h = new hisType();   
Console.WriteLine(h.Foo());

我認為你不能這樣做,因為在CLR世界的任何對象中ToString()總是存在。 看看Eric Lippert的回答

您可以創建一個覆蓋ToString的包裝器類型(帶有隱式轉換)。

class MyType {
    private readonly hisType _hisType;
    private MyType(hisType hisType) {
        _hisType = hisType;
    }
    public static implicit operator MyType(hisType hisType) {
        return new MyType(hisType);
    }
    public override string ToString() {
        return String.Format("a={0},b={1},c={2}", _hisType.a, _hisType.b, _hisType.c);
    }
}

hisType y;
MyType x = y;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM