4

I understand that static methods are not correct for interfaces (see: Why Doesn't C# Allow Static Methods to Implement an Interface?) yet have come up against a situation where I have an object that implements all methods of an interface where all can be static, so I think I must be designing incorrectly.

Trouble is, I cant see any alternative

My interface IDataSerializer is implemented by several classes. One that de/serializes XML, one that does JSON, etc. All of these classes implement the same functions and none have any "state data" (members, etc), but all eventually result in the same type of object being output.

For example, the XML class:

public class MyXmlSerializer : IDataSerializer
{
    public string SerializeFoo(object foo)
    { 
        // uses .Net XML serialzer to serialize foo
    }

    public object DeserializeFoo(string foo)
    { 
        // uses .NET XML serializer to deserialize foo
    }

    // Object type returned by above methods is only ever 
    // used by following method which returns a type available 
    // to all IDataSerializer implementations as this is 
    // the data actually used by the rest of the program

    public IList<Bar> CreateBarList(object deserializedFoo)
    { 
        // does some magic to extract a list of Bar from the 
        // deserialized data, this is the main work for any 
        // IDataSerializer implementation
    }
}

Obviously all of the methods shown above could be static (they all take in all the info they need as parameters and all return the result of their working, there are no members or fields)... but because they should be implemented in a serializer that can do work for any type of serial data (XML,JSON, YAML, etc) then they form an interface... Which is it? Am I thinking about this wrong? Is there an alternative, specific, pattern for achieving what I want to do?

Afterthought: maybe I should simply change my idea of de/serialization being work that something can do to thinking of each implementation as is a serlializer, thus suggesting replacing interface with abstract class?

After-afterthought: overridden methods can't be static either, so changing to abstract class doesn't help any.

Toby
  • 8,602
  • 10
  • 55
  • 118
  • 1
    See also: [Method can be made static, but should it?](https://stackoverflow.com/questions/169378/method-can-be-made-static-but-should-it) – Corak Jul 26 '17 at 09:04
  • 2
    True that all the methods of your interface can be static but they are not required to be static. If you make them static methods of classes `XmlSerializer` or `JsonSerializer` you will lose the benefit of dependency on Contract and be dependent on static classes. And Adding new Serializer class might require you to change your code at lot of places. – Chetan Ranpariya Jul 26 '17 at 09:09
  • 1
    In the context of your example, using a singleton would circumvent the problem of not allowing statics in interfaces, while retaining the spirit of the "one instance" approach that statics introduce. There are distinctions to be made between statics and singletons, but they seem irrelevant to your current case. I understand that your question focuses more on _why_ statics are not allowed in interfaces in any case, but this is a fruitless discussion, no one here is able to change that. – Flater Jul 26 '17 at 12:01
  • @flater thanks for the comment. FYI I'm not asking for the *why* though as such, that's covered by some questions here already. More-so about a specific common pattern to avoid the problem in this case (singleton being one possibility for this) or if my thinking is just in the wrong direction. – Toby Jul 26 '17 at 12:45

1 Answers1

4

From logical point of view these methods should be static, because they logically don't work on a particular instance and don't use shared resources.This class don't have a state as well. But... from a pragmatic point of view, instant class brings many benefits, like:

  • class (interface) if fully testable,
  • follows the OOP and SOLID principles,
  • can be registered as singleton, so you can create only one instance of this object,
  • it's easy to add any dependencies to these classes
  • easy to maintain
  • some useful design patterns can be applied (e.g. decorator, composite)
  • can be lazy loaded and disposed in any time

In your case, in my opinion, you should hide this implementation behind the interface and register it as a singleton, e.g.(using autofac)

builder.RegisterType<MyXmlSerializer>().As<IDataSerializer>().SingleInstance();

In addition, if you need to, you can create an extension method for this interface and add static methods to this contract.

More information can be found here:

Pawel Maga
  • 4,451
  • 3
  • 29
  • 58