C# c中属性的单例模式#
我正在尝试为我的CsvConfiguration属性调整单例策略 如果配置已经可用,只需返回配置即可。否则,获取配置并返回相同的配置,我就能够构建此代码C# c中属性的单例模式#,c#,design-patterns,.net-4.0,.net-4.5,C#,Design Patterns,.net 4.0,.net 4.5,我正在尝试为我的CsvConfiguration属性调整单例策略 如果配置已经可用,只需返回配置即可。否则,获取配置并返回相同的配置,我就能够构建此代码 public Rootpdf pdfConfiguration { get { Rootpdf pdfConfiguration = null; try { if (pdfConfigurati
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,如果它已经可用,我都可以返回它。不需要每次都加载配置文件
并计算配置
我的问题是:重弹手!重竖琴器告诉我们代码
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;
}
}
因为你想要一个单态,我把它变成了一个静态属性。。。希望这是您所需要的。这一行:
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 MySingletonInstance Instance
{
get
{
if (instance == null)
instance = new MySingletonInstance();
return instance;
}
}
通过以下方式调用/实例化:
MySingletonClass msc = MySingletonClass.Instance;
我喜欢上面的第一种方法
我希望这会有所帮助。以下是您的课堂应该是什么样子:
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;
如前所述,这不是一个单一模式
如果您想坚持您描述的想法,那么我会将您的代码更改为:
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;
}
}
内部类配置
{
私有只读惰性配置;
公共配置()
{
_config=newlazy(ReadConfiguration);
}
私有Rootpdf ReadConfiguration()
{
抛出新的NotImplementedException();
}
公共根PDF pdfConfiguration
{
得到
{
尝试
{
返回_config.Value;
}
捕获(例外e)
{
Log.Error(“读取配置文件时出错。”,e);
}
返回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..?
})();
static public Rootpdf pdfConfiguration{get;}=new Func(()=>{
//检索配置文件。
//加载配置并返回它!
return new Rootpdf();//可能是这样的吧。。?
})();
pdfConfiguration
只是一个分配给null
的局部变量,而不是一个持久成员。只使用Lazy
也会更容易一些……这不是单例模式……这是FailAtLazyLoad:EraseAllInformation和TheLoadItallagainBecause YouJustCanPattern™这不是singleton,它不是一种模式:它是一种反模式。@Killercam:对不起,如果我的理解是错误的。根据我的说法,singleton模式如果还不可用,就会返回一些东西。我错在哪里?问题是如果我不这样做,我会得到一个错误,声明“变量可能未初始化”@现在他不应该被解雇了。我想它应该运行得很好。是的,只要它搬出了房子。很好的解释。。Thanks@nowhewhomustnotbenamed.:根据您的编辑建议,我已经更新了我的答案。+1对于静态构造函数也是。。我只是因为他名声不好而接受了另一个答案。。谢谢您的回答。:@now他不应该被命名:不用担心:)“因为你想要一个单身汉,我把它做成了一个静态属性……希望这是你需要的。”+1
var pdf = RootPdf.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;
}
}
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..?
})();