Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在静态容器中包装非静态类_C#_Asp.net - Fatal编程技术网

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

C# 在静态容器中包装非静态类,c#,asp.net,C#,Asp.net,我有很多用于访问数据库的管理器类。我需要创建一个管理器实例,以便访问其方法 因为我个人更喜欢静态类,所以我想知道您对这种方法的看法: public static class Managers { public static SomeManager Manager { get { return new SomeManager(); } } } var stuff = Managers.SomeManager.DoStuff(); 有什么缺点吗?这是的一

我有很多用于访问数据库的管理器类。我需要创建一个管理器实例,以便访问其方法

因为我个人更喜欢静态类,所以我想知道您对这种方法的看法:

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

var stuff = Managers.SomeManager.DoStuff();

有什么缺点吗?

这是的一个糟糕的实现,因为每次调用属性时都会创建一个新实例

这样会更好:

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

最大的缺点是对不熟悉您的代码的人来说不够清晰:对我来说,这样的调用

Managers.SomeManager.DoStuff();
    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;
        }
    }
}
public class YourClass
{
    /// <summary>
    ///     Singleton instance of 
    /// </summary>
    public static YourClass Instance
    {
        get { return Singleton<YourClass>.Instance; }
    }
...methods etc...
}
指访问某种以某种方式固定的管理器,而不是

new SomeManager().DoStuff();
这明确地告诉我,
SomeManager
是按需创建的

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

Managers.MakeSomeManager().DoStuff();

为了隐藏实例化
SomeManager
的过程,您可能需要这样做,其构造函数可能需要一些您不愿意携带的参数。

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

1) 像这样创建singleton类

Managers.SomeManager.DoStuff();
    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;
        }
    }
}
public class YourClass
{
    /// <summary>
    ///     Singleton instance of 
    /// </summary>
    public static YourClass Instance
    {
        get { return Singleton<YourClass>.Instance; }
    }
...methods etc...
}
公共静态类单例
其中T:class,new()
{
/// 
///同步根。
/// 
私有静态只读对象syncRoot=新对象();
/// 
///实例。
/// 
私有静态易失性T实例;
/// 
///获取实例。
/// 
公共静态T实例
{
得到
{
if(实例==null)
{
锁定(同步根)
{
if(实例==null)
{
实例=新的T();
}
}
}
返回实例;
}
}
}
2) 像这样创建类

Managers.SomeManager.DoStuff();
    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;
        }
    }
}
public class YourClass
{
    /// <summary>
    ///     Singleton instance of 
    /// </summary>
    public static YourClass Instance
    {
        get { return Singleton<YourClass>.Instance; }
    }
...methods etc...
}
公共类您的类
{
/// 
///单例
/// 
公共静态类实例
{
获取{return Singleton.Instance;}
}
…方法等。。。
}
3) 从代码中调用您的singleton
YourClass.Instance.SomeMethodCall()

使用单例模式。如果您使用的是.NET 4或更高版本,则最整洁(也是“最懒”的版本)是:


实现线程安全的单例有很多缺陷,因此您应该查看一些提示和示例。

除了每次创建一个新对象这一点之外,我更愿意使用一些DI容器,比如Unityreadonly,这样更好,(不需要检查是否为null)@Sayse,这意味着迫切需要初始化。我更喜欢懒散的方式。生成器方法+1