簡體   English   中英

c#中屬性的單例模式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM