[英]How to implement a singleton in C#?
如何在 C# 中实现 singleton 模式? 我想把我的常量和一些基本函数放在里面,因为我在我的项目中到处都用到它们。 我想让它们“全局”,而不需要在我创建的每个 object 上手动绑定它们。
如果您只是存储一些全局值并且有一些不需要状态的方法,则不需要单例。 只需将类及其属性/方法设为静态即可。
public static class GlobalSomething
{
public static int NumberOfSomething { get; set; }
public static string MangleString( string someValue )
{
}
}
当你有一个普通的有状态的类时,单例是最有用的,但你只想要其中一个。 其他人提供的链接对于探索单例模式应该很有用。
Singleton != Global
。 您似乎正在寻找关键字static
。
只有当这两个条件都为真时,单例才有意义:
请注意,#2,并不意味着你想要的对象只有一个实例-如果多数民众赞成的情况下,简单地初始化它只有一次-这意味着必须有(如,这是危险的,这是不正确的)只能是一个实例。
如果您想要全局,只需创建某个(非符号)对象的全局实例(或使其成为静态或其他)。 如果您只想要一个实例,那么静态是您的朋友。 此外,只需实例化一个对象。
反正这是我的意见。
您可以真正简化单例实现,这就是我使用的:
internal FooService() { }
static FooService() { }
private static readonly FooService _instance = new FooService();
public static FooService Instance
{
get { return _instance; }
}
嗯,这一切似乎有点复杂。
为什么需要依赖注入框架来获取单例? 对于某些企业应用程序来说,使用 IOC 容器是可以的(当然,只要它没有被过度使用),但是,啊,这家伙只是想知道如何实现该模式。
为什么不总是急切地实例化,然后提供一个返回静态的方法,上面写的大部分代码然后就消失了。 遵循古老的 C2 格言 - DoTheSimplestThingThatCouldPossiblyWork...
我建议您阅读 MSDN 上提供的Exploring the Singleton Design Pattern文章。 它详细介绍了使模式易于实现的框架的特性。
顺便说一句,我会查看SO 有关 Singletons的相关阅读。
忽略你是否应该使用单例模式的问题,这已经在别处讨论过,我会像这样实现一个单例:
/// <summary>
/// Thread-safe singleton implementation
/// </summary>
public sealed class MySingleton {
private static volatile MySingleton instance = null;
private static object syncRoot = new object();
/// <summary>
/// The instance of the singleton
/// safe for multithreading
/// </summary>
public static MySingleton Instance {
get {
// only create a new instance if one doesn't already exist.
if (instance == null) {
// use this lock to ensure that only one thread can access
// this block of code at once.
lock (syncRoot) {
if (instance == null) {
instance = new MySingleton();
}
}
}
// return instance where it was just created or already existed.
return instance;
}
}
/// <summary>
/// This constructor must be kept private
/// only access the singleton through the static Instance property
/// </summary>
private MySingleton() {
}
}
如果您想要松散耦合的设计,静态单例几乎是一种反模式。 尽可能避免,除非这是一个非常简单的系统,否则我建议您查看许多可用的依赖注入框架之一,例如http://ninject.org/或http://code.google.com/p /autofac/ 。
要在 autofac 中注册/使用配置为单例的类型,您可以执行以下操作:
var builder = new ContainerBuilder()
builder.Register(typeof(Dependency)).SingletonScoped()
builder.Register(c => new RequiresDependency(c.Resolve<Dependency>()))
var container = builder.Build();
var configured = container.Resolve<RequiresDependency>();
顺便说一句,公认的答案是一个糟糕的解决方案,至少检查实际实施该模式的人。
public class Globals
{
private string setting1;
private string setting2;
#region Singleton Pattern Implementation
private class SingletonCreator
{
internal static readonly Globals uniqueInstance = new Globals();
static SingletonCreator()
{
}
}
/// <summary>Private Constructor for Singleton Pattern Implementaion</summary>
/// <remarks>can be used for initializing member variables</remarks>
private Globals()
{
}
/// <summary>Returns a reference to the unique instance of Globals class</summary>
/// <remarks>used for getting a reference of Globals class</remarks>
public static Globals GetInstance
{
get { return SingletonCreator.uniqueInstance; }
}
#endregion
public string Setting1
{
get { return this.setting1; }
set { this.setting1 = value; }
}
public string Setting2
{
get { return this.setting2; }
set { this.setting2 = value; }
}
public static int Constant1
{
get { reutrn 100; }
}
public static int Constat2
{
get { return 200; }
}
public static DateTime SqlMinDate
{
get { return new DateTime(1900, 1, 1, 0, 0, 0); }
}
}
我喜欢这种模式,尽管它不会阻止某人创建非单例实例。 有时,最好教育团队中的开发人员使用正确的方法,而不是竭尽全力防止某些笨蛋以错误的方式使用您的代码……
public class GenericSingleton<T> where T : new()
{
private static T ms_StaticInstance = new T();
public T Build()
{
return ms_StaticInstance;
}
}
...
GenericSingleton<SimpleType> builder1 = new GenericSingleton<SimpleType>();
SimpleType simple = builder1.Build();
这将为您提供一个实例(以正确的方式实例化)并且实际上是惰性的,因为在调用 Build() 之前不会调用静态构造函数。
您所描述的只是静态函数和常量,而不是单例。 Singleton设计模式(这是很少需要)描述了被实例化,但只有一次,自动,当第一次使用的类。
它将延迟初始化与检查结合起来,以防止多次实例化。 它仅对于包装一些物理上单一的概念的类才真正有用,例如围绕硬件设备的包装器。
静态常量和函数就是这样:根本不需要实例的代码。
问问自己这个问题:“如果有多个实例,这个类会中断吗?” 如果答案是否定的,则不需要单例。
嗯...很少有具有相关功能的常量...通过枚举不是更好吗? 我知道您可以使用方法和所有方法在 Java 中创建自定义枚举,在 C# 中也应该可以实现,如果不直接支持,那么可以使用带有私有构造函数的简单类单例来完成。
如果您的常量在语义上相关,您应该考虑枚举(或等效概念),您将获得 const 静态变量的所有优势 + 您将能够利用编译器的类型检查来发挥您的优势。
我的 2 美分
就我个人而言,我会选择一个依赖注入框架,比如 Unity,它们都能够在容器中配置单例项,并通过从类依赖转移到接口依赖来改善耦合。
通过隐藏公共构造函数,添加一个私有静态字段来保存这个唯一的实例,并添加一个静态工厂方法(带有惰性初始化器)来返回那个单一的实例
public class MySingleton
{
private static MySingleton sngltn;
private static object locker;
private MySingleton() {} // Hides parameterless ctor, inhibits use of new()
public static MySingleton GetMySingleton()
{
lock(locker)
return sngltn?? new MySingleton();
}
}
我使用单例模式为我的项目编写了一个类。 这是非常容易使用。 希望它对你有用。 请找到以下代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TEClaim.Models
{
public class LogedinUserDetails
{
public string UserID { get; set; }
public string UserRole { get; set; }
public string UserSupervisor { get; set; }
public LogedinUserDetails()
{
}
public static LogedinUserDetails Singleton()
{
LogedinUserDetails oSingleton;
if (null == System.Web.HttpContext.Current.Session["LogedinUserDetails"])
{
oSingleton = new LogedinUserDetails();
System.Web.HttpContext.Current.Session["LogedinUserDetails"] = oSingleton;
}
else
{
oSingleton = (LogedinUserDetails)System.Web.HttpContext.Current.Session["LogedinUserDetails"];
}
//Return the single instance of this class that was stored in the session
return oSingleton;
}
}
}
现在您可以像这样在应用程序中为上述代码设置变量值。
[HttpPost]
public ActionResult Login(FormCollection collection)
{
LogedinUserDetails User_Details = LogedinUserDetails.Singleton();
User_Details.UserID = "12";
User_Details.UserRole = "SuperAdmin";
User_Details.UserSupervisor = "815978";
return RedirectToAction("Dashboard", "Home");
}
你可以像这样检索这些值..
public ActionResult Dashboard()
{
LogedinUserDetails User_Details = LogedinUserDetails.Singleton();
ViewData["UserID"] = User_Details.UserID;
ViewData["UserRole"] = User_Details.UserRole;
ViewData["UserSupervisor"] = User_Details.UserSupervisor;
return View();
}
在 c# 中它可能是(线程安全以及延迟初始化):
public sealed class MySingleton
{
static volatile Lazy<MySingleton> _instance = new Lazy<MySingleton>(() => new MySingleton(), true);
public static MySingleton Instance => _instance.Value;
private MySingleton() { }
}
如何在C#中实现单例模式? 我想在我的项目中到处使用常量和一些基本函数。 我想让它们“全局”,而不需要手动绑定我创建的每个对象。
您可以通过将 static 属性实例(名称可以变化)添加到其中并初始化如下,为您的通用(非静态)class 制作一个简单的手册 static singleton 实现:
public class MyClass
{
private static MyClass _instance;
public static MyClass Instance => _instance ?? (_instance = new MyClass());
// add here whatever constructor and other logic you like or need.
}
然后它可以从这个命名空间的任何地方解析,如下所示:
var myClass = MyClass.Instance; // without any new keyword
myClass.SomeNonStaticMethod();
// or:
MyClass.Instance.SomeNonStaticMethod();
// or:
MyClass.Instance.SomeNonStaticProperty = "new value";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.