0

i have a class that (right now) is static:

public static class Grob
{
    public static void Frob()
    {
        Foo.Bar();
    }
}

And that works well. Code calls:

Grob.Frob();

and all is right with the world. Now i want my class to implement an interface:

public static class Grob : IOldNewGrob
{
    public static void Frob()
    {
       Foo.Bar();
    }
}

Unfortunately that does not work, because reasons.

So i would try changing to class to a singleton:

public sealed class Grob
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Grob() {}

   public static Singleton Instance
   {
      get 
      { 
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }
         return instance;
     }
   }       
}

Which works well enough, except that it doesn't work - the code no longer compiles:

Grob.Frob();

In other languages it would not be a problem. i would create a global Grob function (called Grob because that's the name that existing code needs):

function Grob(): GrobSingleton;
{
   return Grob.Instance;
}

//and rename Grob class to something else
public sealed class GrobSinglton
{
   ...
}

except that C# doesn't have global functions.

In the end:

  • i don't need a global function
  • i don't need a static class to be able to implement an interface
  • i don't need a singleton

i just want it all to work.

Community
  • 1
  • 1
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219

1 Answers1

10

Why not just create a singleton which also has a static Frob method?

public sealed class Grob : IOldNewGrob
{
    private static readonly Grob instance = new Grob();

    public static Grob Instance { get { return instance; } }

    // Prevent external instantiation
    private Grob() {}

    public static void Frob()
    {
        Foo.Bar();
    }

    // Implement IOldNewGrob here
}

You should probably also read my article on implementing the singleton pattern in .NET - there's really no need to implement the fragile double-checked locking pattern.

That satisfies both of your requirements of making Grob.Frob() work, and making Grob implement an interface. It's not clear whether those are your only requirements though - you haven't really explained why you're trying to do that - where the singleton or the interface come in.

EDIT: If the idea was that Frob was a member of IOldNewGrob, you can use explicit interface implementation like this:

public sealed class Grob : IOldNewGrob
{
    private static readonly Grob instance = new Grob();

    public static Grob Instance { get { return instance; } }

    // Prevent external instantiation
    private Grob() {}

    public static void Frob()
    {
        // Implementation
    }

    // Explicit interface implementation to prevent name collisions
    void IOldNewGrob.Frob()
    {
        // Call the static implementation
        Frob();
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Delegate implementation of my methods to....myself! Nice. **Edit:** Why not do that? Cause i didn't think of it. The singleton doesn't come in anywhere; it wasn't one before 25 minutes ago. The interface comes in when people take an `IOldNewGrob` rather than a `Grob`. – Ian Boyd Jun 11 '12 at 17:55
  • Oh, wait. i can't have `public static void Frob()` and `public void Frob()`. *Lemme check Jon's answer* Oh, you created a new `Foo` class. Perhaps using interfaces is overrated. – Ian Boyd Jun 11 '12 at 18:05
  • @IanBoyd There are various [libraries](http://code.google.com/p/impromptu-interface/) that will take a static class and an interface and generate a proxy class at runtime, delegating the interface method implementations to the corresponding static method. Whether the overhead of an extra dependency and one-time runtime code generation is worth it is a call you'll have to make. It will probably result in simpler code. – cdhowie Jun 11 '12 at 18:13
  • @IanBoyd: I didn't create a new `Foo` class. I copied your implementation from the first piece of code in the question. It wasn't clear what you were trying to do, and you never explained that `Frob` was part of the interface. (This is where a *complete* example really helps.) You can use explicit interface implementation for this. Will edit... – Jon Skeet Jun 11 '12 at 19:16