C# c中属性的单例模式#

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

我正在尝试为我的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,如果它已经可用,我都可以返回它。不需要每次都加载配置文件 并计算配置

我的问题是:重弹手!重竖琴器告诉我们代码

   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..?
})();