4

Edit: Clearly this is not possible as C# does not allow static methods in interfaces.

Obviously it would be fairly simple to implement the following interfaces for your own solution

public interface IParsable<T>
{
    T Parse(string s);
}

public interface ITryParsable<T> : IParsable<T>
{
    bool TryParse(string s, out T output);
}

Having been writing various ways of parsing unknown typed user input data, I would have found having int, decimal, etc, etc implement a version of these interfaces indispensable.

To me it seems like a fairly obvious thing to have included in the System namespace.

Obviously this is not the case. So what is the best way of seeing whether a class "implements" these interfaces?

Checking whether the method exists via Duck Typing seems like a sensible alternative, but Reflection isn't terribly performant.

Community
  • 1
  • 1
dav_i
  • 26,475
  • 17
  • 99
  • 133
  • _"What is the best way of getting around this?"_ - if "this" is an interface missing in the base class library, then you have no other option than to manually write the interface. Can you try to explain your actual problem? I suppose you have a variable of some type, and you want to try to parse it as any other type and see which one works? – CodeCaster Dec 09 '13 at 14:20
  • 8
    Those are static methods (they create an instance, so on which instance would you call them?). Interfaces only support instance methods. – CodesInChaos Dec 09 '13 at 14:22
  • @CodesInChaos D'oh. Great point. – dav_i Dec 09 '13 at 14:24
  • "but Reflection isn't terribly performant." - With a bit of caching it's pretty fast. I've written [such a caching parser](http://stackoverflow.com/questions/4956575/assigning-type-at-runtime/4956763#4956763) – CodesInChaos Dec 09 '13 at 14:24
  • @CodesInChaos Thanks, looks good. *FEELING RATHER STUPID AT THE MOMENT* (it's Monday). – dav_i Dec 09 '13 at 14:29
  • FYI, I think you meant to ask why .NET doesn't have `IParsable`, not C#. – John Saunders Dec 09 '13 at 15:21

2 Answers2

5

Since C# does not support static interfaces, you would have to have an instance of the object in order to call the parse method. You would end up with something like this:

var a = new int().Parse<int>("123");
var b = 123.Parse("567");

Or with the TryParse method things get even more weird:

int x;
if (x.TryParse("456", out x))
    // trippy... now imagine that x is a reference type...
MattDavey
  • 8,641
  • 3
  • 30
  • 54
  • `var p = default(int); p.Parse("567"); Console.WriteLine(p);` doesn't look *too* bad to me, though I do admit it's confusing enough that it probably isn't worth the effort. –  Dec 09 '13 at 14:30
  • @CodesInChaos the constructor parentheses were missing. Edited. – MattDavey Dec 09 '13 at 14:36
  • @hvd, if this is OK for you, you can always write the corresponding extension methods, as this will be possible in C# – Ivaylo Slavov Dec 09 '13 at 14:37
  • Even with parentheses the code makes no sense. Calling a generic `Parse` method on an instance of `Object`. How would that enable interfaces? – CodesInChaos Dec 09 '13 at 14:59
  • @IvayloSlavov It might be possible with extension methods (I'm not sure, can you have a `this ref` parameter for value types?), but it's not possible to add interfaces to built-in types, so the generic advantage wouldn't apply anyway. Edit: no, `this ref` is not valid, even for value types, so it's not possible, even with extension methods. –  Dec 09 '13 at 15:45
  • @hvd, I agree there will be no advantage because you will have to write extension methods for all types you need to have these methods on: `int` , `double` and etc. So you may have: `public static int Parse(this int @this, string value) { return int.Parse(value); }` The same for `int.TryParse` . I have never mentioned `this ref` in any way and I am unable to see your point on that. Sorry for misunderstanding, I'd be glad if you clarify. – Ivaylo Slavov Dec 10 '13 at 08:21
  • 1
    @IvayloSlavov In my example, I used `p.Parse("567");` which would modify `p`. This is possible with instance methods on `int`, but not with extension methods on `int`. –  Dec 10 '13 at 08:37
  • @hvd, I see what you had in mind then. Unfortunately, no, it will not be possible again, as `int` is an immutable type. The extension methods I spoke of will make possible for this to be valid: `default(int).Parse("567");` which will return another integer. In similar fashion `"abc234".Replace("3", "0")` will return another string instance. I seem to have missed the last line in your example `Console.WriteLine(p);` that subjects to mutability of `p`. – Ivaylo Slavov Dec 10 '13 at 08:58
0

With .NET 6 Preview Generic Math, this does exist!

Parse and TryParse are in the new INumber interface

Adam Dernis
  • 506
  • 3
  • 13