在C#中实现类的静态/单例接口

Ian*_*oyd 0 c# singleton static-class

我有一个(现在)是静态的类:

public static class Grob
{
    public static void Frob()
    {
        Foo.Bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

这很有效.代码电话:

Grob.Frob();
Run Code Online (Sandbox Code Playgroud)

一切都与世界是对的.现在我希望我的类实现一个接口:

public static class Grob : IOldNewGrob
{
    public static void Frob()
    {
       Foo.Bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用,因为原因.

所以我会尝试更改为单个类:

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;
     }
   }       
}
Run Code Online (Sandbox Code Playgroud)

哪个工作得很好,除了它不起作用 - 代码不再编译:

Grob.Frob();
Run Code Online (Sandbox Code Playgroud)

在其他语言中,这不是问题.我会创建一个全局Grob函数(Grob因为这是现有代码所需的名称):

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

//and rename Grob class to something else
public sealed class GrobSinglton
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

除了C#没有全局函数.

到底:

  • 不需要全局功能
  • 不需要静态类来实现接口
  • 不需要单身人士

我只想让一切顺利.

Jon*_*eet 10

为什么不创建一个有静态Frob方法的单例?

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
}
Run Code Online (Sandbox Code Playgroud)

您可能还应该阅读我在.NET中实现单例模式的文章 - 实际上没有必要实现脆弱的双重检查锁定模式.

这既满足了您的Grob.Frob()工作要求,也使Grob工具成为一个界面.目前尚不清楚这些是否是你唯一的要求 - 你还没有真正解释为什么你要这样做 - 单身人士或界面进来.

编辑:如果想法是Frob成员IOldNewGrob,你可以使用这样的显式接口实现:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)