David H
David H

Reputation: 1625

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

I've got somebody's F# library with a type in it:

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.

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?

Upvotes: 3

Views: 324

Answers (4)

Eric Lippert
Eric Lippert

Reputation: 660493

As others have pointed out, the ToString on object will always be a better match than your extension method. 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 might be used for something other than debugging. 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.

Upvotes: 11

Daniel
Daniel

Reputation: 47914

You could create a wrapper type (with an implicit conversion) that overrides 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;

Upvotes: 0

Tigran
Tigran

Reputation: 62265

I think you can not do that, as ToString() is always there, in any object of CLR world. Check out Eric Lippert answer.

Upvotes: 3

phoog
phoog

Reputation: 43066

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

Upvotes: 6

Related Questions