检查c#初始化后是否定义了对象

时间:2016-09-15 20:51:15

标签: c# .net object if-statement syntax

我有以下对象(类)。

let trimmed_len = correct_name.trim_right().len();
correct_name.truncate(trimmed_len);

以下类使用上述对象,因此按如下方式初始化对象:

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;

但值可以定义为0 ......所以我不确定如何解决这个问题。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

这些原则可用于解释描述,样本和简要评估/意见的问题。

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。使用可空类型

Nullable类型添加&#34;额外&#34;对于类型的价值,&#34; undefined&#34;州。引用类型(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&#39; s响应),并简化外部有效性检查,但在课堂上有更多代码,需要更深入思考。

就个人而言,我更喜欢不变性。它可以编写更多的猴子代码,但由于设计简洁,它肯定会得到回报。

没有广泛的知识,没有不可变性的复杂系统很难推理。在团队中工作时尤其痛苦 - 通常每个人只知道代码库的一部分。

令人遗憾的是,并不总是有可能使evertything不可变(例如viewmodels):然后我倾向于尽快将对象转换为内部不可变模型。

答案 1 :(得分:0)

鉴于您已撰写的内容,我会将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)即可。注意'Initialized'属性的私有setter,它将确保外部代码不会意外设置此标志。

根据您的需要,您可以进一步将参数初始化直接传递给Initialize()方法作为参数。

答案 2 :(得分:0)

你有几种方法,比如强制值在构造函数中是正确的,或者有另一个变量告诉对象是否还没有值,比如System.Drawing.Point有静态&#34;空&#34;属性。但是在你的简单对象的情况下,你的主类是显式创建一个CurrentClass的实例,所以此时这个对象应该是正确的,并且应该设置系数。如果您依赖其他一些代码来设置这些值以便稍后执行某些其他操作,则此处超出了这两个对象的范围。

更新:perharps分享真正问题的细节会更好,因为我有一种感觉试图提供一个简化的例子,最终隐藏了真正的问题。