在静态容器中包装非静态类

时间:2013-09-12 12:53:39

标签: c# asp.net

我有很多用于访问数据库的管理器类。我需要创建一个管理器实例才能访问它的方法。

由于我个人更喜欢静态类,我想知道你对这种方法的看法:

public static class Managers
{
    public static SomeManager Manager
    {
         get { return new SomeManager(); }
    }
}

var stuff = Managers.SomeManager.DoStuff();

有任何缺点吗?

4 个答案:

答案 0 :(得分:6)

最大的缺点是不熟悉你的代码的人不清楚:对我来说,这样的电话

Managers.SomeManager.DoStuff();

表示以某种方式访问​​SomeManager,而不是

new SomeManager().DoStuff();

它明确告诉我SomeManager是按需创建的。

SomeManager属性转换为具有适当名称的方法,例如MakeSomeManager(),将恢复可读性:

Managers.MakeSomeManager().DoStuff();

你可能想要做这样的事情,以隐藏实例化SomeManager的过程,其构造函数可能需要一些你不愿意随身携带的参数。

答案 1 :(得分:4)

这是singleton pattern的错误实现,因为每次调用属性时都会创建一个新实例。

这会更好:

public static class Managers
{
    private static SomeManager someManagerInstance;

    public static SomeManager Manager
    {
         get
         {
             if (someManagerInstance == null)
             {
                 someManagerInstance = new SomeManager();
             }
             return someManagerInstance;
         }
    }
}

除非当然需要每次都有新实例?在这种情况下,我会将创建包装在方法中,而不是属性:

public static class Managers
{
    public static SomeManager GetNewManager()
    {
         return new SomeManager();
    }
}

答案 2 :(得分:2)

使用Singleton模式。如果你使用的是.NET 4或更高版本,那么最新的(和最懒的版本)是:

public sealed class SomeManager
{
    private static readonly Lazy<SomeManager> lazy = 
        new Lazy<SomeManager>(() => new SomeManager());

    public static SomeManager Instance { get { return lazy.Value; } }

    private SomeManager()
    {
    }
}

然后通过以下方式访问它:

var stuff = SomeManager.Instance.DoStuff();

实现一个线程安全的单例有很多陷阱,所以你应该查看this的一些提示和示例。

答案 3 :(得分:0)

你可以使用单例,因为使用静态类和这样的方法是不好的做法。例如,尝试为您的实现编写一些单元测试,否则......

1)像这样创建单例类

    public static class Singleton<T>
    where T : class, new()
{
    /// <summary>
    /// The syncRoot.
    /// </summary>
    private static readonly object syncRoot = new object();

    /// <summary>
    /// The instance.
    /// </summary>
    private static volatile T instance;

    /// <summary>
    /// Gets the instance.
    /// </summary>
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new T();
                    }
                }
            }

            return instance;
        }
    }
}

2)像这样创建你的课程

public class YourClass
{
    /// <summary>
    ///     Singleton instance of 
    /// </summary>
    public static YourClass Instance
    {
        get { return Singleton<YourClass>.Instance; }
    }
...methods etc...
}

3)从代码中调用你的单身人士     YourClass.Instance.SomeMethodCall();