[英]Singleton pattern for a property in c#
我正在嘗試為我的 CsvConfiguration 屬性調整單例策略。
如果配置已經可用,只需返回配置。 否則,獲取配置並返回相同的內容,我就可以構建此代碼。
public Rootpdf pdfConfiguration
{
get
{
Rootpdf pdfConfiguration = null;
try
{
if (pdfConfiguration == null)
{
//retrieve the configuration file.
//load the configuration and return it!
}
else
{
return pdfConfiguration;
}
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
}
return pdfConfiguration;
}
}
優點(我希望):每當需要我的 pdfConfiguration 時,如果它已經可用,我可以將其退回。 無需每次加載配置文件並計算配置。
我的問題:磨刀器! resharper 告訴代碼
if (pdfConfiguration == null) //The expression is always true.
resharper 真的有問題,它不明白我在遵循這種單例模式嗎?
要么
我根本沒有遵循單例模式嗎?
您在 get 子句的頂部將單例設置為 null:
Rootpdf pdfConfiguration = null;
//THIS IS THE PROBLEM.
注:99%的時間,ReSharper的是比你聰明。 我不喜歡它,但這是真的。
認為你必須使用 getter 中的局部變量
private static Rootpdf _pdfConfiguration ;
public static Rootpdf pdfConfiguration
{
get
{
try
{
if (_pdfConfiguration == null)
{
//retrieve the configuration file.
//load the configuration and return it!
}
else
{
return _pdfConfiguration;
}
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
}
return _pdfConfiguration;
}
}
因為你想要一個單身人士,我把它變成了一個靜態屬性......希望它是你需要的。
這是您的班級應有的樣子:
public class RootPdf
{
private static RootPdf instance;
private RootPdf()
{
//retrieve the configuration file.
//load the configuration and return it!
}
public static RootPdf Instance
{
get
{
if (instance == null)
{
try
{
instance = new RootPdf();
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
return null;
}
}
return instance;
}
}
}
以下是您將如何調用對象:
var pdf = RootPdf.Instance;
這一行: if (pdfConfiguration == null)
由於這一行(就在之前)將始終為真Rootpdf pdfConfiguration = null;
. 您需要做的是將最后一行( Rootpdf pdfConfiguration = null;
)放在Get
方法之外。 這將停止每次將變量初始化為 null。
private static Rootpdf pdfConfiguration = null;
public Rootpdf PdfConfiguration
{
get
{
try
{
if (pdfConfiguration == null)
....
有關單例模式的更多信息可在此處獲得。
或者,您可以使用靜態構造函數:
靜態構造函數用於初始化任何靜態數據,或執行只需要執行一次的特定操作。 在創建第一個實例或引用任何靜態成員之前自動調用它。
public class Foo {
private static Rootpdf pdfConfiguration = null;
static Foo()
{
pdfConfiguration = ....
}
public Rootpdf pdfConfiguration
{
get
{
return pdfConfiguration;
}
....
class MySingletonClass
{
private static UserSettings instance = null;
/// <summary>
/// Default protected constructor.
/// </summary>
protected MySingletonClass()
{
}
/// <summary>
/// Invoke the singleton instance.
/// </summary>
public static MySingletonClass Instance()
{
if (instance == null)
instance = new MySingletonClass();
return instance;
}
}
這將被調用/實例化
MySingletonClass msc = MySingletonClass.Instance();
您還可以使用訪問器/屬性來返回實例
public MySingletonInstance Instance
{
get
{
if (instance == null)
instance = new MySingletonInstance();
return instance;
}
}
通過以下方式調用/實例化
MySingletonClass msc = MySingletonClass.Instance;
我喜歡上面的第一種方法。
我希望這有幫助。
如前所述,這不是單例模式。
如果您想堅持您所描述的想法,那么我會將您的代碼更改為:
internal class Config
{
private readonly Lazy<Rootpdf> _config;
public Config()
{
_config = new Lazy<Rootpdf>(ReadConfiguration);
}
private Rootpdf ReadConfiguration()
{
throw new NotImplementedException();
}
public Rootpdf pdfConfiguration
{
get
{
try
{
return _config.Value;
}
catch (Exception e)
{
Log.Error("An error occurred while reading the configuration file.", e);
}
return null;
}
}
如今,我認為從 C# 6.0 開始,您可以將初始值與屬性一起使用,如下所示:
static public Rootpdf pdfConfiguration { get; } = new Func<Rootpdf>(() => {
//retrieve the configuration file.
//load the configuration and return it!
return new Rootpdf(); // Something like this perhaps..?
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.