簡體   English   中英

檢查在C#中初始化后是否定義了對象

[英]Check if object is defined after initialization in c#

我有以下對象(類)。

namespace Temp.Models
{
    public class CurrentClass
    {
        private double _firstCoefficient;
        private double _secondCoefficient;

        public double FirstCoefficient
        {
            get { return _firstCoefficient; }
            set { _firstCoefficient= value; }
        }
        public double SecondCoefficient
        {
            get { return _secondCoefficient; }
            set { _secondCoefficient= value; }
        }
    }
}

下列類利用上述對象,因此按如下所示初始化該對象:

namespace Temp.Models
{
    public class MainClass
    {
        private CurrentClass _currentClass = new CurrentClass();

        public CurrentClass CurrentClass
        {
            get { return _currentClass; }
            set { _currentClass = value; }
        }
    }
}

在某些時候,如果滿足某些條件,我將定義變量如下:

MainClass currentObject = new MainClass();
//if conditions are met
currentObject.CurrentClass.FirstCoefficient = 0;
currentObject.CurrentClass.SecondCoefficient = 5;

但是,如果永不滿足條件並且我也從未定義上述變量,該怎么辦? 如何和/或什么是檢查對象是否從未定義的最佳方法?

我可以進行以下檢查:

if(currentObject.CurrentClass.FirstCoefficient != 0 && currentObject.CurrentClass.SecondCoefficent != 0)

但是這些值可以定義為0 ...所以我不確定該怎么做。

任何幫助深表感謝!

這些是可用於解決問題的一些原理,包括描述,示例和簡短評估/意見。

1.通過構造函數進行參數化

根據OOP原理,構造函數是用於將對象初始化為有效狀態的方法。 不變性的概念使這一點更進一步,不允許進行任何更改,從而完全避免了無效狀態。

在對象的API禁止無效狀態的情況下,也存在折衷的可能性。

有了這個概念,您將到達:

namespace Temp.Models
{
    public class CurrentClass
    {
        public double FirstCoefficient { get; private set; }
        public double SecondCoefficient { get; private set; }

        public CurrentClass(double firstCoefficient, double secondCoefficient)
        {
            FirstCoefficient = firstCoefficient;
            SecondCoefficient = secondCoefficient;
        }

        // if mutability is required - this is needless as the constructor is
        // the same but if there was more complex state, methods like this would make
        // sense, mutating only parts of the state
        public void SetCoefficients(double firstCoefficient, double secondCoefficient)
        {
            FirstCoefficient = firstCoefficient;
            SecondCoefficient = secondCoefficient;
        }
    }
}

摘要:

  • CurrentClass每個實例始終處於有效狀態,從而避免了很多一致性檢查(改進了封裝)

  • 需要花費更多的代碼來編寫(但由於前一點,您還節省了很多其他代碼)

  • 您需要事先知道系數。

2.使用可為空的類型

可空類型將“附加”值添加到類型的“未定義”狀態。 引用類型( class )在設計上是可為空的,而值類型( struct )則需要標記為可為空,可以將其標記為Nullable<T>或簡寫T?

然后,這允許對象處於無效狀態並對其進行特定處理。 由於具有多個可為空字段的對象具有許多無效狀態,因此從不變性到一致性尺度的另一端。

樣例代碼:

namespace Temp.Models
{
    public class CurrentClass
    {
        public double? FirstCoefficient { get; set; }
        public double? SecondCoefficient { get; set; }
    }
}

現在,它可以很好地實例化,並且可以隨時更改:

public CurrentClass CreateCurrentClass()
{
    var currentClass = new CurrentClass { FirstCoefficient = 1.0 };
    var secondCoefficient = RetrieveSecondCoefficient();
    currentClass.SecondCoefficient = secondCoefficient;

    return currentClass;
}

但是,在使用該對象的任何地方都需要進行有效性檢查。

public bool IsValid(CurrentClass currentClass)
{
    // what if FirstCoefficient has value and SecondCoefficient doesn't,
    // is that always an invalid state?
    return currentClass.FirstCoefficient.HasValue
        && currentClass.SecondCoefficient.HasValue;
}

摘要:

  • 只需很少的代碼即可啟動DTO並運行

  • 要使用這種模型,需要進行大量的一致性檢查(以及相關的腦痛)

  • 缺乏封裝-采用CurrentClass任何方法都可以更改其有效性,因此使上一點更糟。 可以通過在需要只讀訪問權限的情況下使用傳遞的只讀接口來緩解這種情況。

加起來

通常在上述兩種方法之間還存在許多其他手段。 例如,您可以為每個對象使用一個有效性標志(SergeyS的響應),並簡化外部有效性檢查,但該類中包含更多代碼,並且需要更深入的思考。

就個人而言,我更喜歡不變性。 它要寫的猴子代碼更多,但肯定要歸功於簡潔的設計。

如果沒有廣泛的知識,就很難推理出沒有不變性的復雜系統。 在團隊中工作時尤其痛苦-通常每個人只知道部分代碼庫。

可悲的是,並非總是有一切不變的(例如,視圖模型):然后,我傾向於盡快將對象轉換為內部不變的模型。

給定您已經寫的內容,我將Initialize()方法和Initialized屬性添加到您的MainClass類中。 類似於以下內容:

public class MainClass
{
    private CurrentClass _currentClass = new CurrentClass();

    public CurrentClass CurrentClass
    {
        get { return _currentClass; }
        set { _currentClass = value; }
    }

    public bool Initialized {get; private set;}

    public void Initialize()
    {
        this.CurrentClass.FirstCoefficient = 0;
        this.CurrentClass.SecondCoefficient = 5;

        this.Initialized = true;
    }
}

在滿足條件的地方調用Initialize()方法。 稍后在代碼中,您可以僅檢查if(currentObject.Initialized) 注意“初始化”屬性的私有設置器,它將確保該標志不是由外部代碼意外設置的。

根據您的需要,您可以更進一步,並將用於初始化的參數直接作為參數傳遞給Initialize()方法。

您有幾種方法,例如在構造函數中使力值正確,或者有另一個變量來告知對象是否還沒有值,例如System.Drawing.Point具有靜態的“ Empty”屬性。 但是,在這種簡單對象的情況下,您的主類將顯式創建CurrentClass的實例,因此此時該對象應該是正確的,並且應該設置系數。 如果您依賴其他代碼來設置這些值以在以后執行其他操作,則此處超出了這兩個對象的范圍。

更新:分享真正問題的細節會更好,因為我有一種嘗試提供一個簡化的示例,但最終卻隱藏了真正的問題,所以感覺更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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