简体   繁体   English

可以将C#扩展方法添加到F#类型中吗?

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

I've got somebody's F# library with a type in it: 我有一个人的F#库,里面有一个类型:

module HisModule

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

I'm using it in C#, and I would like to add a "ToString()" method to it, in order to facilitate debugging. 我在C#中使用它,我想为它添加一个“ToString()”方法,以便于调试。

But the following doesn't seem to work: 但以下似乎不起作用:

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"

Any ideas why not? 任何想法为什么不呢?

As others have pointed out, the ToString on object will always be a better match than your extension method. 正如其他人所指出的,对象上的ToString总是比你的扩展方法更好的匹配。 You should probably change the signature of your extension method; 您应该更改扩展方法的签名; changing the name is probably the right way to go. 更改名称可能是正确的方法。

Moreover: you said that the purpose of this thing was to facilitate debugging. 而且:你说这个东西的目的是为了方便调试。 Overriding ToString might be the wrong thing to do there; 重写ToString可能是错误的做法; ToString might be used for something other than debugging. ToString可能用于除调试之外的其他内容。 I would be inclined to make my own specially-named method whose name clearly reflects the purpose of the method. 我倾向于制作我自己特别命名的方法,其名称清楚地反映了该方法的目的。

If you are creating a new type and want to have special display behaviour in the debugger, the easiest thing to do is to use the Debugger Display Attributes . 如果要创建新类型并希望在调试器中具有特殊的显示行为,则最简单的方法是使用调试器显示属性

If you want to get really fancy to display a complex data structure in an interesting way, consider writing a Debugger Visualizer . 如果您想真正想要以有趣的方式显示复杂的数据结构,请考虑编写一个Debugger Visualizer

The answer to your question is "yes". 你的问题的答案是“是”。 Your sample does not succeed, however, because method resolution succeeds when it finds object.ToString() , so the compiler never looks for extension methods. 但是,您的示例不成功,因为方法解析在找到object.ToString()时成功,因此编译器永远不会查找扩展方法。 Try it with a different name: 尝试使用其他名称:

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

I think you can not do that, as ToString() is always there, in any object of CLR world. 我认为你不能这样做,因为在CLR世界的任何对象中ToString()总是存在。 Check out Eric Lippert answer . 看看Eric Lippert的回答

You could create a wrapper type (with an implicit conversion) that overrides ToString . 您可以创建一个覆盖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