Li Haoyi
Li Haoyi

Reputation: 15812

How to switch on generic-type-parameter in F#?

I have the following C# code:

public static T Attr<T>(this XElement x, string name)
    {
        var attr = x.Attribute(name);
        if (typeof(T) == typeof(int))
            return (T)(object)(attr == null ? 0 : int.Parse(attr.Value));

        if (typeof(T) == typeof(float))
            return (T)(object)(attr == null ? 0 : float.Parse(attr.Value));
        if (typeof(T) == typeof(String))
            return (T)(object)(attr == null ? "" : attr.Value);
        return (T)(object)null;
    }

I've been trying for an hour or so to translate this into F# but haven't had any success, and keep getting error messages like "type int has no subtype..." which have me completely befuddled. My exploration of the bestiary of :? :?> and other operators haven't given me any success.

How would I go about re-writing this in F#?

Upvotes: 0

Views: 251

Answers (1)

Daniel
Daniel

Reputation: 47914

If you want the same logic, you could use if/else's just like C#, or define a map of types to "type converters." But I would probably opt for something simpler, like this:

type XElement with
  member this.Attr<'T>(name) = 
    match this.Attribute(XName.Get name) with
    | null -> Unchecked.defaultof<'T>
    | attr -> Convert.ChangeType(attr.Value, typeof<'T>) :?> 'T

Upvotes: 3

Related Questions