如何在C#中實現單例模式?我想把我的常量和一些基本功能放在裏面,因爲我在我的項目中使用這些功能。我想讓他們成爲'全球',而不需要手動綁定他們創建的每個對象。如何在C#中實現一個單例?
回答
如果你只是存儲一些全局值,並有一些不需要狀態的方法,你不需要單例。只需使該類及其屬性/方法靜態。
public static class GlobalSomething
{
public static int NumberOfSomething { get; set; }
public static string MangleString(string someValue)
{
}
}
當你有一個普通的狀態類,但你只需要其中的一個時,單身最有用。其他人提供的鏈接應該有助於探索Singleton模式。
我建議您閱讀MSDN上的文章Exploring the Singleton Design Pattern。它詳細介紹了使模式易於實現的框架功能。
Singleton != Global
。您似乎在尋找關鍵字static
。
單身才有意義,如果這些條件都爲真:
- 的對象必須是全球
- 必須有永遠只存在於對象的單例如
請注意,#2並不意味着你會像對象只有一個實例 - 如果是這種情況,只需實例化一次 - 這意味着有必須(因爲這是非常危險的)只能是單個實例。
如果你想全球化,只需要製作一些(非signleton)對象的全局實例(或使其成爲靜態或其他)。 如果你只想要一個實例,靜態是你的朋友。另外,只需實例化一個對象。
這就是我的意見無論如何。
忽視的你是否應該使用Singleton模式,它已在別處討論過這個問題,我想實現這樣的單身:
/// <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>();
接受的答案是順便說一個可怕的解決辦法,至少檢查究竟是誰實施的傢伙該模式。
你真的可以簡化單的實現,這是我用:
internal FooService() { }
static FooService() { }
private static readonly FooService _instance = new FooService();
public static FooService Instance
{
get { return _instance; }
}
你所描述僅僅是靜態函數和常量,不單身。單例設計模式(這是很少需要的)描述了一個類,是實例化,但只有一次,自動,當第一次使用。
它將延遲初始化與檢查相結合以防止多個實例化。這對於包裝一些物理上單一的概念的類非常有用,例如硬件設備的包裝。
靜態常量和函數就是這樣的:完全不需要實例的代碼。
問問自己:「如果這個類有多個實例,它會中斷嗎?」如果答案是否定的,你不需要單身。
嗯...幾乎沒有相關函數的常量......通過枚舉不會更好嗎?我知道你可以使用方法和所有方法在Java中創建一個自定義枚舉,但如果不直接支持,那麼在C#中也應該可以實現,然後可以使用具有私有構造函數的簡單類單例執行。
如果你的常量是語義相關的,你應該考慮枚舉(或等價概念),你將獲得const static變量的所有優點+你將能夠使用你的優勢編譯器的類型檢查。
我2%的
通過隱藏公共構造,加入了私有靜態字段來保存這個唯一實例,並添加靜態工廠方法(懶初始化),以返回單一實例
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();
}
}
就個人而言,我會去尋找一個像Unity這樣的依賴注入框架,它們都可以在容器中配置單例項目,並且可以通過從類依賴轉移到接口依賴來改善耦合。
嗯,這一切似乎有點複雜。
爲什麼你需要一個依賴注入框架來獲得一個singleton?使用國際奧委會容器對於某些企業應用程序來說是不錯的選擇(只要它當然不會被過度使用),但是,這傢伙只是想知道實施這種模式的方式。
爲什麼不總是急於實例化,然後提供一個返回靜態的方法,大部分上面寫的代碼就會消失。按照老C2的格言 - DoTheSimplestThingThatCouldPossiblyWork ...
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模式寫了一個類。這是非常容易使用。希望它能爲你工作。請查找以下代碼。
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();
}
- 1. MDI單實例C#..如何實現?
- 2. 如何使全局在C#中實現一個實例?
- 3. 在Rails中實現一個單例
- 4. 如何實現一個無限循環的單例模式 - C#
- 5. 如何在perl中實現單例類?
- 6. 如何在單例類中實現Map?
- 7. 如何在C#中實例化一個屬性的新實例
- 8. 哪個單例實現更好C#
- 9. 如何在C#中實現一個簡單的通用比較#
- 10. 在C#中實現一個.NET接口實例化IronPython類型
- 11. 在Objective C中創建單例類的另一個實例
- 12. 實現OAuth2.0的一個簡單例子
- 13. 如何實現「單實例」式設計?
- 14. C#:我如何實例化一個類在C#中,像舒本C++例子
- 15. 如何在C++中實例化一個成員變量中的子類實例?
- 16. 如何實例化Bill Pugh方法中實現的單例類?
- 17. 如何在Python中實現Haskell實例?
- 18. 單例實現
- 19. 如何在C++中創建一個類的多個實例
- 20. 如何在C++中創建一個簡單的單例類?
- 21. 在實體框架中實現「每個對象一個實例」
- 22. 如何在C++中訪問一個向量中的子實例
- 23. 如何在運行時在C#中實例化一個類
- 24. 在C#中保留一個WebDriver實例
- 25. 在一個實現中DI和單例模式
- 26. C# - 如何實現IEnumerator一個類
- 27. 如何實現一個單身模型
- 28. 如何實現一個祕密菜單
- 29. 如何簡單地實現一個KeyListener?
- 30. 如何實現一個近單身?
我想你應該考慮選票並重新考慮你接受的答案。 – 2008-10-29 13:35:09
我不知道 - tvanfosson的回答對於問題的主體來說很好,即使它不是標題。可以說,改變身體或標題以匹配對方將是最好的:) – 2008-10-29 14:04:33
同意你在那 – 2008-10-29 14:49:53