【问题标题】:How to add a list of class objects to a class?如何将类对象列表添加到类中?
【发布时间】:2019-02-13 10:15:40
【问题描述】:

我有 3 个班级:House、Apartment 和 Resident。每个类都有字符串名称等基本属性。问题是如何在它们之间创建这样的链接:

1。 House 类应该有 Apartment 属性(Apartments as List (?) 因为一个 House 可以有多个 Apartments)

2。公寓类与财产House(single)(公寓所在的房子)。还收集(列表?)居民(住在公寓里的人)。

3。带公寓(单人)物业的居民类。

我已经使用继承创建了这些类的结构,但它不起作用 - 不能在没有指定 Apartment 的情况下创建 House,不能添加没有 House 的 Apartment 等等。

public class House
{
    public int number { get; set; }
    public string street { get; set; }
    public List<Apartment> apartments = new List<Apartment>();
}
public class Apartment:House
{
    public int apt_number { get; set; }
    public int apt_Rooms { get; set; }
    public House house;
    public List<Resident> residents = new List<Resident>();
}
public class Resident
{   public string name {get;set;}
    public string surname {get;set}
    public Apartment apartment {get;set}
}

【问题讨论】:

  • 为什么Apartment继承自House?.公寓是否有街道并包含其他公寓?
  • 如上所述——除非你将访问修饰符更改为House的属性,否则你不应该从它继承——否则逻辑有缺陷。

标签: c# polymorphism


【解决方案1】:

如 cmets 所述,让 Apartment 继承 House (似乎)没有用。如果你删除了继承,你可以创建一些引用 House 对象的 Apartment 对象,并将它们添加到 House 中的 Apartment 列表中。

House house = new House();
Apartment app1 = new Apartment { house = house };
Apartment app2 = new Apartment { house = house };
Apartment app3 = new Apartment { house = house };

house.apartments = new List<Apartment>{ app1, app2, app3 };

【讨论】:

    【解决方案2】:

    继承与组合不同。当您从 A 继承 B 时,您会说“B A”。在您的情况下,当您从 House 继承 Apartment 时,您说的是“ApartmentHouse”。这显然不是真的,因为公寓不是房子,它是房子的一部分。所以Apartment 不应该继承自House

    属于的关系用组合来表达。您已通过将公寓列表添加到 House(并将 House 属性添加到 Apartment)来做到这一点。

    但是,您通常希望保持父列表和子列表的父属性之间的完整性。例如,当您将Apartment 添加到House 时,您希望相应地设置Apartment.House

    使用List&lt;T&gt; 无法完成此行为。实际上List&lt;T&gt; 并不是为了公开这种公共属性,而是为了内部数据存储。出于您的目的,您需要一个System.Collections.ObjectModel.Collection&lt;T&gt;,它允许您进行所需的自定义。

    这就是HouseApartment 之间的关系的工作方式。你需要为ApartmentResident 做同样的事情:

    public class House
    {
        public int Number { get; set; }
        public string Street { get; set; }
        public ApartmentCollection Apartments { get; private set; }
    
        public House() {
            Apartments = new ApartmentCollection(this);
        }
    }
    
    public class Apartment
    {
        private House house;
    
        public int AptNumber { get; set; }
        public int AptRooms { get; set; }
        public House House {
            get {
                return house;
            }
            set {
                house?.Apartments.Remove(this);
                house = value;
                house?.Apartments.Add(this);
            }
        }
        public List<Resident> Residents = new List<Resident>();
    }
    
    public class ApartmentCollection : Collection<Apartment> {
        private readonly House parent;
    
        public ApartmentCollection(House parent) {
            this.parent = parent;
        }
    
        protected override void InsertItem(int index, Apartment item) {
            if (item == null) {
                throw new ArgumentNullException(nameof(item));
            }
            if (Contains(item)) {
                return;
            }
    
            base.InsertItem(index, item);
            item.House = parent;
        }
    
        protected override void SetItem(int index, Apartment item) {
            if (item == null) {
                throw new ArgumentNullException(nameof(item));
            }
    
            Apartment oldItem = this[index];
            if (oldItem.Equals(item)) {
                return;
            }
    
            int oldIndexOfItem = IndexOf(item);
            base.SetItem(index, item);
            oldItem.House = null;
            item.House = parent;
    
            //If the item was in the collection before, remove it from its old position
            if (oldIndexOfItem >= 0) {
                base.RemoveItem(oldIndexOfItem);
            }
        }
    
        protected override void RemoveItem(int index) {
            Apartment removedItem = this[index];
            base.RemoveItem(index);
            removedItem.House = null;
        }
    
        protected override void ClearItems() {
            Apartment[] removedItems = new Apartment[Count];
            CopyTo(removedItems, 0);
            base.ClearItems();
            foreach(Apartment removedItem in removedItems) {
                removedItem.House = null;
            }
        }
    }
    

    现在您可以同时设置Apartment.House 或从House.Apartments 添加和删除项目。另一面总是会自动更新。此外,ApartmentCollection 将防止两次添加相同的公寓或向公寓集合添加 null 值。 List&lt;T&gt; 两者都没有。

    【讨论】:

      【解决方案3】:

      Sefe 就您的课程提出了一个很好的问题。

      你不应该让 Apartment 从 House 继承。

      如果你让我们说一个带有属性的类“水果”,这个概念就更有意义了。然后你有一些特定的类,如“Apple”或“Pear”,它们继承自“Fruit”。它们都具有相同的水果属性,并且还自带。

      要解决您的具体问题:您忘记了一些';'我删除了继承。 此外,您还没有为公寓内的列表或房产指定 get 或 set。要创建类的变量,请参见上面来自 Aars93 的帖子。

      public class House
      {
          public int number { get; set; }
          public string street { get; set; }
          public List<Apartment> apartments = new List<Apartment>();
      }
      
      public class Apartment
      {
          public int apt_number { get; set; }
          public int apt_Rooms { get; set; }
          public House house;
          public List<Resident> residents = new List<Resident>();
      }
      
      public class Resident
      {   public string name {get;set;}
          public string surname {get;set;}
          public Apartment apartment {get;set;}
      }
      

      【讨论】:

        猜你喜欢
        • 2019-05-29
        • 1970-01-01
        • 2013-02-05
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-14
        相关资源
        最近更新 更多