如何在 C# 中创建一个完美的 Singleton 类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10239765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a perfect Singleton class in c#?
提问by fiberOptics
I want to store some data with Singleton class. As far as I've studied, singleton class can be instantiated only for once. But it doesn't work for me. Can someone correct my code:
我想用 Singleton 类存储一些数据。据我研究,单例类只能实例化一次。但这对我不起作用。有人可以更正我的代码:
public class MvcApplication : System.Web.HttpApplication
{
Singleton clientsessionidinstance = Singleton.GetInstance();
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "MVCPrj.Controllers" }
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
LOGICcLASSES.Logic.Auth ca = new LOGICcLASSES.Logic.Auth();
clientsessionidinstance = Singleton.GetInstance();
clientsessionidinstance.ClientSessionID = ca.Login(new LOGICcLASSES.Entities.ClientAuthentication()
{
IP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"],
UserName = ConfigurationManager.AppSettings["ClientUserName"],
Password = ConfigurationManager.AppSettings["ClientPassword"]
});
}
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (System.Web.HttpContext.Current.Session != null)
{
if (!string.IsNullOrEmpty(clientsessionidinstance.ClientSessionID))
{
CurrentUserSession.Store<string>("ClientSessionID", clientsessionidinstance.ClientSessionID);
}
}
}
}
So the goal is this, @ Application_StartI have to log in an account. Then I should save the return string on HttpContext.Current.Session.
Unfortunately I can't access the HttpContext.Current.Sessioninside Application_Startbut it is possible on Application_AcquireRequestState.
I can use a variable that will hold the returned string and then use its value inside the Application_AcquireRequestState, but the big problem is this, the page loads? twice, so if I will use a variable, it will become nullat the second load but Application_Startis still initiated once.
So I came up using a Singleton class, but still I get null values on second load.
所以目标是这样的,@Application_Start我必须登录一个帐户。然后我应该将返回字符串保存在HttpContext.Current.Session.
不幸的是,我无法进入HttpContext.Current.Session内部,Application_Start但可以在Application_AcquireRequestState.
我可以使用一个变量来保存返回的字符串,然后在 中使用它的值Application_AcquireRequestState,但最大的问题是,页面加载了吗?两次,所以如果我将使用一个变量,它将null在第二次加载时变为但Application_Start仍会启动一次。
所以我想出了使用单例类,但我仍然在第二次加载时得到空值。
Singleton class:
单例类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MVCPrj.Areas.WebPage.Logic
{
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton GetInstance()
{
lock (typeof(Singleton))
{
instance = new Singleton();
}
return instance;
}
private string _ClientSessionID;
public string ClientSessionID
{
get { return _ClientSessionID; }
set { _ClientSessionID = value; }
}
}
}
EDIT
编辑
This code works for me after reading Singleton
public class Singleton
{
private static readonly object _mutex = new object();
private static volatile Singleton _instance = null;
private Singleton() { }
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (_mutex)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
private string _ClientSessionID;
public string ClientSessionID
{
get { return _ClientSessionID; }
set { _ClientSessionID = value; }
}
}
采纳答案by Ian Mercer
If you are using .NET4 the "perfect singleton" is often best achieved using System.Lazy.
如果您使用 .NET4,“完美单例”通常最好使用System.Lazy实现。
See also this web pagefor a description of many different singleton patterns in C# and their various pros and cons.
另请参阅此网页,了解 C# 中许多不同的单例模式及其各种优缺点。
回答by John3136
public static Singleton GetInstance()
{
lock (typeof(Singleton))
{
instance = new Singleton();
}
return instance;
}
You only need to create a new instance if the member instance is null. You seem to be doing it all the time.
如果成员实例为空,则只需创建一个新实例。你似乎一直都在这样做。
回答by David.Chu.ca
Actually, you can place the new in the variable definition if its CTOR is default one (no parameters):
实际上,如果它的 CTOR 是默认值(无参数),您可以将 new 放在变量定义中:
public sealed class Singleton {
public readonly Singleton Instance = new Singleton();
...
}
See Exploring the Singleton Design Pattern
请参阅探索单例设计模式
回答by Cade Roux
I've always used this generic base class for my singletons:
我一直为我的单身人士使用这个通用基类:
public class SingletonBase<T> where T : class
{
static SingletonBase()
{
}
public static readonly T Instance =
typeof(T).InvokeMember(typeof(T).Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic,
null, null, null) as T;
}
回答by u1230329
public sealed class Singleton
{
public static readonly Singleton Instance =new Singleton();
private Singleton(){}
}//end
this is the best SINGLETON I've ever seen.
这是我见过的最好的SINGLETON。
it is simple but thread-safe without using locks.
它简单但线程安全,无需使用锁。
you can also make the 'Instance' as a property with a '_instance' field.
您还可以将“ Instance”作为带有“ _instance”字段的属性。
回答by novicegis
I use such singleton and I do not have problems:
我使用这样的单身人士,我没有问题:
public sealed class Settings
{
private static readonly Lazy<Settings> lazy =
new Lazy<Settings>(() => new Settings());
public static Settings Instance { get { return lazy.Value; } }
private Settings()
{
_fileName = "Settings.ini";
}
....
}
回答by Razan Paul
Singleton
单身人士
using System;
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
Static Initialization
静态初始化
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Multithreaded Singleton
多线程单例
using System;
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
Source: Implementing Singleton in C#
来源:在 C# 中实现单例

