C# - 如何将List设置为至少包含一个元素?

时间:2015-12-08 19:22:08

标签: c# list serialization

我有以下问题:

我有一个名为MedicalInfo的课程,我希望其列表中至少有一个Prescription。事情是我想在它的构造函数中拟合一些逻辑,正如你在下面看到的那样,但它有一个主要的骗局:当我反序列化它(xml)时,它会添加一个新的。

我认为Serializer首先创建对象(并因此添加一个Prescription的实例),然后添加字段的值。所以,简而言之,每次我反序列化时我都会得到一个额外的实例......我怎么能避免这种情况?

为了提供一些上下文,我正在开发一个WinForms应用程序,该应用程序在应用程序关闭时序列化并在其打开时反序列化,以便在使用期间获得可用的数据。此外,MedicalInfo是名为Client的类的一部分,该类具有许多属性,例如,一个是策略列表。我序列化和反序列化的是客户列表(地址簿)。我想在反序列化后进行“检查”......但在某些情况下,这需要双重预测。我不确定这是否是最佳的。

public class MedicalInfo
{
    public string MedicareNumber { get; set; }
    public DateTime PartAEffectiveDate { get; set; }
    public DateTime PartBEffectiveDate { get; set; }
    public List<Prescription> Prescriptions { get; set; }

    public MedicalInfo()
    {
        PartAEffectiveDate = new DateTime(1900, 01, 01);
        PartBEffectiveDate = new DateTime(1900, 01, 01);
        Prescriptions = new List<Prescription>().Min(1);

        if (Prescriptions.Count == 0)
        {
            Prescriptions.Add(new Prescription());
            Prescriptions.FirstOrDefault().Instructions = "Default Prescription";
        }
    }
}

public class Client
{
    #region Properties

    private Guid ID { get; set; }

    [XmlIgnore]
    public string FullName
    {
        get
        {
            return FirstName + " " + MiddleName + " " + LastName;
        }
    }
    [XmlIgnore]
    public string DisplayName
    {
        get
        {
            return LastName + ", " + FirstName;
        }
    }

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public bool Male { get; set; }
    public DateTime Birthday { get; set; }
    public Address Address { get; set; }
    public int SSN { get; set; }
    public long Phone { get; set; }
    public long AlternatePhone { get; set; }
    public string Email { get; set; }
    public int Height { get; set; }
    public int Weight { get; set; }
    public string Notes { get; set; }

    public BankAccount BankInfo { get; set; }
    public MedicalInfo MedInfo { get; set; }

    public DateTime RegisteredTime { get; set; }

    #endregion Properties

    public Client()
    {
        ID = new Guid();
        RegisteredTime = DateTime.Now;

        Birthday = new DateTime(1900, 01, 01);
        BankInfo = new BankAccount();
        MedInfo = new MedicalInfo();
        Address = new Address();
    }
}

public class InsuranceClient : Client
{
    public bool Tobacco { get; set; }
    public PolicyCollection Policies { get; set; }

    public InsuranceClient() : base()
    {
        Policies = new PolicyCollection();

        if (Policies.Count == 0)
        {
            Policies.Add(new Policy());
            Policies.FirstOrDefault().Plan = "Default Policy";
        }
    }
}

2 个答案:

答案 0 :(得分:0)

添加成员变量以存储处方。将业务规则添加到Prescriptions属性的getter中。

public class MedicalInfo
{
    public string MedicareNumber { get; set; }
    public DateTime PartAEffectiveDate { get; set; }
    public DateTime PartBEffectiveDate { get; set; }

    private List<Prescription> _prescritpions;
    public List<Prescription> Prescriptions
    {
        get
        {
            if (_prescritpions.Count == 0)
            {
                _prescritpions.Add(new Prescription
                {
                    Instructions = "Default Description"
                });
            }

            return _prescritpions;
        }
        set
        {
            _prescritpions = value;
        }
    }

    public MedicalInfo()
    {
        PartAEffectiveDate = new DateTime(1900, 01, 01);
        PartBEffectiveDate = new DateTime(1900, 01, 01);

        _prescritpions = new List<Prescription>();
    }
}

编辑:从构造函数中删除了处方的无法实例化。

答案 1 :(得分:0)

您需要从构造函数中删除初始化。我建议使用下面详述的null-coalescing operator ??

public class MedicalInfo
{
    public string MedicareNumber { get; set; }
    public DateTime PartAEffectiveDate { get; set; }
    public DateTime PartBEffectiveDate { get; set; }

    public List<Prescription> Prescriptions
    {
        get
        {
            return _prescritpions ?? (_prescritpions = GetDefaultPrescriptions());
        }
        set
        {
            _prescritpions = value;
        }
    }
    List<Prescription> _prescritpions;

    public MedicalInfo()
    {
        PartAEffectiveDate = new DateTime(1900, 01, 01);
        PartBEffectiveDate = new DateTime(1900, 01, 01);
    }

    static List<Prescription> GetDefaultPrescriptions()
    {
        return new List<Prescription> 
               { 
                   new Prescription { Instructions = "Default Description" }     
               };
    }
}

优点是如果_perscriptions变量已经实例化 - 它将只返回。否则,如果它是null,它将使用GetDefaultPrescriptions函数中指定的默认实例对其进行实例化。这应该可以防止重复创建与序列化问题一起找到的默认变量。