【问题标题】:Static/singleton interface implementing class in C#C#中的静态/单例接口实现类
【发布时间】:2012-06-14 15:22:22
【问题描述】:

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

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

而且效果很好。代码调用:

Grob.Frob();

世界上一切都很好。现在我希望我的类实现一个接口:

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

不幸的是,这不起作用,因为reasons

所以我会尝试将班级改为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;
     }
   }       
}

效果很好,只是它不起作用-代码不再编译:

Grob.Frob();

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

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

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

除了 C# 没有全局函数。

最后:

  • 我不需要全局函数
  • 我不需要静态类来实现接口
  • 我不需要单身

我只是希望一切正常。

【问题讨论】:

  • 你为什么不能打电话给Grob.Instance.Frob()?这就是单例的工作方式。
  • @cdhowie 我可以打电话给Grob.Instance.Frob();但现有代码没有。

标签: c# singleton static-class


【解决方案1】:

为什么不直接创建一个有静态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
}

您可能还应该阅读我的article on implementing the singleton pattern in .NET - 确实没有必要实现脆弱的双重检查锁定模式。

这满足了使Grob.Frob() 工作和使Grob 实现接口的要求。目前尚不清楚这些是否是您的唯一要求 - 你还没有真正解释为什么你试图这样做 - 单例或接口的来源。

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

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();
    }
}

【讨论】:

  • 将我的方法的实现委托给....我自己!好的。 编辑: 为什么不这样做呢?因为我没有想到。单例不会出现在任何地方。 25 分钟前还没有。当人们使用IOldNewGrob 而不是Grob 时,界面就会出现。
  • 哦,等等。我不能拥有public static void Frob()public void Frob()让我看看 Jon 的答案 哦,你创建了一个新的 Foo 类。也许使用接口被高估了。
  • @IanBoyd 有各种libraries,它们将采用静态类和接口并在运行时生成代理类,将接口方法实现委托给相应的静态方法。额外依赖和一次性运行时代码生成的开销是否值得是您必须进行的调用。它可能会导致更简单的代码。
  • @IanBoyd:我没有创建新的Foo 类。我从问题的第一段代码中复制了您的实现。不清楚您要做什么,并且您从未解释过Frob 是界面的一部分。 (这是 complete 示例真正有帮助的地方。)您可以为此使用显式接口实现。将编辑...
猜你喜欢
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 2012-05-17
  • 2021-03-08
  • 2016-01-15
  • 1970-01-01
  • 2017-08-21
  • 2016-05-06
相关资源
最近更新 更多