3

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?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
David H
  • 1,461
  • 2
  • 17
  • 37
  • 1
    Note that every object in .NET already has a ToString() member method. – DuckMaestro Nov 30 '11 at 21:36
  • possible duplicate of [How to create extension method for toString?](http://stackoverflow.com/questions/4982479/how-to-create-extension-method-for-tostring) – ildjarn Nov 30 '11 at 21:43

4 Answers4

11

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.

svick
  • 236,525
  • 50
  • 385
  • 514
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
6

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());
phoog
  • 42,068
  • 6
  • 79
  • 117
3

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

Community
  • 1
  • 1
Tigran
  • 61,654
  • 8
  • 86
  • 123
  • I've been adding ToString() extension methods on enum types in the past so I don't think this is definitely the problem, resolution should fall back on Object.ToString() last. – David Grenier Nov 30 '11 at 22:29
  • 2
    @DavidGrenier: Overload resolution *always* prioritizes an applicable candidate method on a base type over an extension method. Can you demonstrate a situation where C# does not do so? If so, you've found a bug and I'd like to know about it. Thanks! – Eric Lippert Dec 01 '11 at 15:58
  • I tried repeating the experiment in LINQPad and it didn't work. I might just be crazy here. This was done at a previous workplace and the evidences are clearly against. – David Grenier Dec 01 '11 at 21:19
0

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;
Daniel
  • 47,404
  • 11
  • 101
  • 179