c#中属性的单例模式

时间:2013-08-07 08:56:36

标签: c# design-patterns .net-4.0 .net-4.5

我正在尝试为我的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! resharper告诉代码

   if (pdfConfiguration == null) //The expression is always true.

它是否真的是resharper的问题,它不明白我遵循这个单例模式?

我根本不遵循单身人士模式吗?

7 个答案:

答案 0 :(得分:5)

您在get子句的顶部将单例设置为null:

Rootpdf pdfConfiguration = null;
//THIS IS THE PROBLEM.

注意:99%的时间,ReSharper 比你聪明。我不喜欢它,但这是真的。

答案 1 :(得分:4)

认为你必须使用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;
        }
    }

如你想要一个单身人士,我把它变成了一个静态属性......希望这就是你所需要的。

答案 2 :(得分:2)

以下是您的课程应该是什么样的:

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;

答案 3 :(得分:1)

此行:if (pdfConfiguration == null)将始终为真,因为此行(就在之前)Rootpdf pdfConfiguration = null;。您需要做的是将最后一行(Rootpdf pdfConfiguration = null;)放在Get方法之外。这将使变量每次都被初始化为null。

private static Rootpdf pdfConfiguration = null;
public Rootpdf PdfConfiguration
{

    get
    {            
        try
        {
            if (pdfConfiguration == null)
    ....

有关单身人士模式的更多信息,请here

或者,您可以使用Static Constructor

  

静态构造函数用于初始化任何静态数据,或者   执行仅需要执行一次的特定操作。它   在创建第一个实例或任何实例之前自动调用   静态成员被引用。

public class Foo {
private static Rootpdf pdfConfiguration = null;
static Foo()
{
    pdfConfiguration = ....
}
public Rootpdf pdfConfiguration
{
    get
    {
        return pdfConfiguration;
    }
 ....

答案 4 :(得分:1)

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;

我喜欢上面的第一种方法。

我希望这会有所帮助。

答案 5 :(得分:1)

如前所述,这不是单身人士模式。

如果您想坚持您所描述的想法,那么我会将您的代码更改为:

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;
            }
        }

答案 6 :(得分:0)

现在,我认为从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..?
})();