如何创建一个由对象“拥有”的集合?

时间:2011-05-26 16:17:52

标签: c# c#-4.0

继续提出这个问题Good class design by example我有一个后续问题。

我想创建一些由其他对象拥有的集合。回顾一下,我有一个Person课程,我希望Person能够拥有一个或多个Addresses。所以我想我会创建一个Address类和一个Addresses集合。合理?到目前为止,这是我的代码

class Person
{
    public Person(int SSN, string firstName, string lastName)
    {
        this.SSN = SSN;
        FirstName = firstName;
        LastName = lastName;
    }

    public int SSN { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Address
{
    public Address(string line1, string postCode)
    {
        Line1 = line1;
        PostCode = postCode;
    }

    public int ID { get; set; }
    public string Line1 { get; set; }
    public string PostCode { get; set; }
}

class Addresses : System.Collections.CollectionBase
{
    public int Person { get; set; } // should this be of type Person?

    public void Add(Address addy)
    {
        List.Add(addy);
    }

    public Address Item(int Index)
    {
        return (Address)List[Index];
    }

    public void Remove(int index)
    {
        List.RemoveAt(index);            
    }
}

如何将多个地址与人员关联?我想在Main中执行类似的操作:

Person p = new Person(123,"Marilyn","Manson");
Address a = new Address("Somewhere", "blahblah");
p.Addresses.Add(a);

然后我希望能够将地址保存到数据库中。我应该Address.Save()还是Addresses.Save()(或其他什么)?

我如何更改代码来实现它?谢谢你的期待。

5 个答案:

答案 0 :(得分:2)

如果您想要人员拥有的地址,该人员应该包含地址集合

class Person 
{     
     <all the stuff you have>
     List<Address> Addresses;
}

不要忘记在构造函数中新建它,

然后添加一个地址

Address addressInstance = new Address(){...};
PersonInstance.Addresses.Add( addressInstance );

卡尔 -

答案 1 :(得分:1)

如果Person“拥有”地址,则应该公开Addresses属性。这可以是ReadonlyCollection<Address>类型 - 无需创建自己的集合类型。

public Person  {
  private List<Address> _addresses;
  public ReadonlyCollection<Address> Addresses {
    get { return _addresses.AsReadOnly(); }
  }
  public void AddAddress(Address address) {
    _addresses.Add(address);
  }
}

如果您正在考虑良好的课堂设计,请三思而后行,是否每个属性都需要一个二传手。也许你希望你的对象不可变,在这种情况下你会想要私有的setter。

“保存”将遵循“ActiveRecord”模式。更常见的,例如当使用像NHibernate这样的ORM时,你的对象会越过某个边界,这个边界表明存储了它。在NHibernate中,这称为Session,它根据可用信息保存对象。

答案 2 :(得分:0)

每个地址都应该保存()。您的地址可以保存,可以在每个子节点上调用保存。

您可能希望拥有一个具有可枚举状态的基类,以便您拥有New,Modified,UnModified和Deleted,以便您可以选择调用CRUD的哪个部分。有些人把它分开,所以你有布尔,isNew,isModified,isDeleted。

答案 3 :(得分:0)

这取决于您的架构......但是,为了保存地址,我不会使用Address对象来执行此操作。这是你的POCO(普通的旧CLR对象),它不应该知道DAL。另一个类应该处理CRUD(Creat Read Update Delete)操作,它应该是业务层中与DAL交互的部分。也许叫它AddressComponent.cs?这是一种领域模型模式方法。

对于地址集合,您可以像flq一样说并将其作为属性...除非您需要额外的逻辑,否则实际上不需要另外一个名为Addresses.cs的对象。

答案 4 :(得分:0)

我会使用泛型来派生List(或任何其他集合类)

// This class add just an Owner (parent) to the list
public class OwnedList<T> : List<T>
{
    public Object Owner { set; get; }

    public OwnedList(Object owner)
    {
        Owner = owner;
    }
}

然后在你的班级中传递对象本身:

class Contact
{
    public int Person { get; set; }

    private OwnedList<Address> _Addresses;
    public OwnedList<Address> Addresses
    {
        get
        {
            if (_Addresses == null)
            {
                _Addresses = new OwnedList<Address>(this);
            }
            return _Addresses;
        }

        set
        {
            _Addresses = value;
            _Addresses.Owner = this;
        }
    }       
}