Static generic extension method

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Steffen Bobek

    Static generic extension method

    Extension methods are made for use with instances. I'd like to "misuse" them
    as static methods, too. Let me tell you my ambition:

    I use an extension method to serialize objects somehow like this:

    MyObject obj = new MyObject();
    obj.ToXmlFile(" some directory\\some file.xml");

    The method "ToXmlFile" is defined elsewhere far apart from MyObject to work
    for all objects:

    public static void ToXmlFile<T>(th is T obj, string path)
    {
    //do the right thing
    }

    And of course there is another method being a "classic" static method that
    reads the XML file and deserializes its contents:

    public static T FromXmlFile<T>( string path)
    {
    //do the right thing the other way round
    }

    That method is called:

    MyObject obj = MyXmlSerializer Class.FromXmlFi le<MyObject>("s omewhere");

    Now my question is: Can you think of a possibility to define "FromXmlFil e"
    in some way that allows me to call it more convenient? i.e.:

    MyObject obj = MyObject.FromXm lFile("somewher e");

    A solution that does also work for 3rd party objects whose code I can't
    manipulate? i.e.:

    TheirObject obj = TheirObject.Fro mXmlFile("somew here");

    Something one might call "static extension method"?
    I'd really appreciate any hints!

    Thanks in advance,
    Steffen


  • Jeroen Mostert

    #2
    Re: Static generic extension method

    Steffen Bobek wrote:
    Extension methods are made for use with instances. I'd like to "misuse" them
    as static methods, too.
    Short of creating your own C# variant, you can't, end of story.
    Let me tell you my ambition:
    >
    OK, so maybe it's not.
    I use an extension method to serialize objects somehow like this:
    >
    MyObject obj = new MyObject();
    obj.ToXmlFile(" some directory\\some file.xml");
    >
    The method "ToXmlFile" is defined elsewhere far apart from MyObject to work
    for all objects:
    >
    public static void ToXmlFile<T>(th is T obj, string path)
    {
    //do the right thing
    }
    >
    Hmm. This sounds far inferior to having a class whose job it is to
    serialize. Something like, I don't know, XmlSerializer. Static methods are
    quite inflexible, and serialization is one of those things where relying on
    the One True Approach for everything will probably get you in trouble.

    Even if you don't like XmlSerializer, the basic approach of that is sound:
    use an object to serialize. Creating an object is more flexible than calling
    a static method (as there are more ways of doing the former than doing the
    latter). That object can also reuse any run-time structures that need to be
    built for serializing a given type. Doing such caching for a static method
    will just involve creating similar objects in the background, at increased
    bookkeeping overhead.

    Aside from that, using an extension method for this just seems wrong.
    Extension methods are supposed to provide additional functionality for
    specific types. Defining one that works on any T is like extending Object
    itself, and that's pretty far-reaching. It makes it harder to reason about
    classes and objects in terms of responsibilitie s: there are no classes or
    objects responsible for serialization in your model, it's actually this one
    method that's doing the work -- even thought it *appears* as if individual
    objects are responsible.
    And of course there is another method being a "classic" static method that
    reads the XML file and deserializes its contents:
    >
    public static T FromXmlFile<T>( string path)
    {
    //do the right thing the other way round
    }
    >
    That method is called:
    >
    MyObject obj = MyXmlSerializer Class.FromXmlFi le<MyObject>("s omewhere");
    >
    Now my question is: Can you think of a possibility to define "FromXmlFil e"
    in some way that allows me to call it more convenient? i.e.:
    >
    MyObject obj = MyObject.FromXm lFile("somewher e");
    >
    A solution that does also work for 3rd party objects whose code I can't
    manipulate? i.e.:
    >
    TheirObject obj = TheirObject.Fro mXmlFile("somew here");
    >
    Something one might call "static extension method"?
    C# just doesn't support that, and there's really nothing to be gained from
    it. Extension methods are a double-edged sword as it is: they're bad for
    readability as it's not immediately clear where a method is coming from, and
    they're good for readability as they preserve traditional O-O semantics in
    absence of developer clairvoyance.

    Static methods on classes are not traditional O-O semantics, though, and the
    minor readability gain they offer in a scenario like this doesn't weigh
    against the drawbacks extension methods have.

    --
    J.

    Comment

    • Steffen Bobek

      #3
      Re: Static generic extension method

      Jeroen, thank you for your reply.

      Let me put my approach straight. I think every developer's goal is to write
      easily readable and understandable code. And to me this is (amongst others)
      excellently done by extension methods, because you write significantly less
      code and separate your code by functionality at the same time (in my case
      XML serialization is coded in one place only).

      Since XmlSerializer itself seems to me like a giant static method (you can
      put in any object to have it serialized to XML), I didn't see something
      wrong to embed it into an extension method that provides exactly this
      funcionality to any object.

      My implementation works really fine. It's just the deserialization call that
      annoys me, because I imagined the shorter option "AnyObject obj =
      AnyObject.FromX mlFile(path)" (to get back to my approach).

      But I understand that it's impossible to implement "static extension
      methods", sadly. Thanks for your note about that!

      Steffen


      "Jeroen Mostert" <jmostert@xs4al l.nlschrieb im Newsbeitrag
      news:47fff9ec$0 $14344$e4fe514c @news.xs4all.nl ...
      Steffen Bobek wrote:
      >Extension methods are made for use with instances. I'd like to "misuse"
      >them as static methods, too.
      >
      Short of creating your own C# variant, you can't, end of story.
      >
      >Let me tell you my ambition:
      >>
      OK, so maybe it's not.
      >
      >I use an extension method to serialize objects somehow like this:
      >>
      > MyObject obj = new MyObject();
      > obj.ToXmlFile(" some directory\\some file.xml");
      >>
      >The method "ToXmlFile" is defined elsewhere far apart from MyObject to
      >work for all objects:
      >>
      > public static void ToXmlFile<T>(th is T obj, string path)
      > {
      > //do the right thing
      > }
      >>
      Hmm. This sounds far inferior to having a class whose job it is to
      serialize. Something like, I don't know, XmlSerializer. Static methods are
      quite inflexible, and serialization is one of those things where relying
      on the One True Approach for everything will probably get you in trouble.
      >
      Even if you don't like XmlSerializer, the basic approach of that is sound:
      use an object to serialize. Creating an object is more flexible than
      calling a static method (as there are more ways of doing the former than
      doing the latter). That object can also reuse any run-time structures that
      need to be built for serializing a given type. Doing such caching for a
      static method will just involve creating similar objects in the
      background, at increased bookkeeping overhead.
      >
      Aside from that, using an extension method for this just seems wrong.
      Extension methods are supposed to provide additional functionality for
      specific types. Defining one that works on any T is like extending Object
      itself, and that's pretty far-reaching. It makes it harder to reason about
      classes and objects in terms of responsibilitie s: there are no classes or
      objects responsible for serialization in your model, it's actually this
      one method that's doing the work -- even thought it *appears* as if
      individual objects are responsible.
      >
      >And of course there is another method being a "classic" static method
      >that reads the XML file and deserializes its contents:
      >>
      > public static T FromXmlFile<T>( string path)
      > {
      > //do the right thing the other way round
      > }
      >>
      >That method is called:
      >>
      > MyObject obj =
      >MyXmlSerialize rClass.FromXmlF ile<MyObject>(" somewhere");
      >>
      >Now my question is: Can you think of a possibility to define
      >"FromXmlFile " in some way that allows me to call it more convenient?
      >i.e.:
      >>
      > MyObject obj = MyObject.FromXm lFile("somewher e");
      >>
      >A solution that does also work for 3rd party objects whose code I can't
      >manipulate? i.e.:
      >>
      > TheirObject obj = TheirObject.Fro mXmlFile("somew here");
      >>
      >Something one might call "static extension method"?
      >
      C# just doesn't support that, and there's really nothing to be gained from
      it. Extension methods are a double-edged sword as it is: they're bad for
      readability as it's not immediately clear where a method is coming from,
      and they're good for readability as they preserve traditional O-O
      semantics in absence of developer clairvoyance.
      >
      Static methods on classes are not traditional O-O semantics, though, and
      the minor readability gain they offer in a scenario like this doesn't
      weigh against the drawbacks extension methods have.
      >
      --
      J.

      Comment

      • =?ISO-8859-1?Q?Arne_Vajh=F8j?=

        #4
        Re: Static generic extension method

        Jeroen Mostert wrote:
        Steffen Bobek wrote:
        >Let me put my approach straight. I think every developer's goal is to
        >write easily readable and understandable code. And to me this is
        >(amongst others) excellently done by extension methods, because you
        >write significantly less code and separate your code by functionality
        >at the same time (in my case XML serialization is coded in one place
        >only).
        >>
        Extension methods aren't all roses and sunshine, though. They also have
        drawbacks:
        >
        - The former assumption that a call of the form A.B() involves a method
        .B() defined either in class A or one of its base classes no longer
        holds. The definition of .B() could be anywhere in the set of referenced
        classes. UI support is critical.
        >
        - To be able to use .B(), you must be aware that it's an extension
        method, so you can reference the proper assembly and use the proper
        namespace. It's not longer clear what A offers just by reading source code.
        >
        - In the same vein, generating useful documentation becomes harder:
        either the extension methods are integrated with A (which requires that
        all known assemblies offering extensions should have their documentation
        generated in one big set) or they're left in the documentation for the
        extension class (which makes .B() harder to look up for clients of A).
        >
        - The author of A will be unaware of extension methods. If they make a
        breaking change, the extension methods may stop working. Of course, the
        same would happen to code in a static method, but the nature of the
        extension method makes it unclear who is responsible for .B().
        In my opinion extensions methods are like operator overloads.

        Very valuable in the few cases where it makes sense.

        Should not be used in most cases.

        Arne

        Comment

        • Anders Borum

          #5
          Re: Static generic extension method

          Hi!
          In my opinion extensions methods are like operator overloads.
          Very valuable in the few cases where it makes sense.
          Should not be used in most cases.
          I completely agree. And although some voice that writing less code is not
          that important, I feel that it leads to more readable and elegant code. And
          when extending standard types from the BCL (such as XmlNode etc.), it's
          really not that hard to determine, whether a method came from the actual
          type or an extension.

          Use where appropriate, not just because it's possible.

          --
          With regards
          Anders Borum / SphereWorks
          Microsoft Certified Professional (.NET MCP)

          Comment

          Working...