我有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}
}
答案 0 :(得分:1)
如评论中所述,(似乎)使Apartment继承房屋没有任何用处。如果删除该继承关系,则可以参考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 };
答案 1 :(得分:1)
粘着力与成分不同。当您从B
继承A
时,您说“ B
是是A
”。就您而言,当您从Apartment
继承House
时,您是在说“ Apartment
是House
”。这显然是不正确的,因为公寓不是房屋,所以它是房屋的一部分。因此,Apartment
不应从House
继承。
成为的一部分的关系由组成表示。您可以通过向House
添加公寓列表(向House
添加Apartment
属性)来实现这一点。
但是,您通常希望保持父级列表和子级父级属性之间的完整性。例如,当您向Apartment
添加House
时,您希望相应地设置Apartment.House
。
List<T>
无法实现此行为。实际上,List<T>
并不是公开为这种公共属性,而是公开用于内部数据存储。为了您的目的,您需要一个System.Collections.ObjectModel.Collection<T>
来实现所需的自定义。
这是House
和Apartment
之间关系的工作方式。您需要对Apartment
和Resident
做同样的事情:
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<T>
都不做。
答案 2 :(得分:0)
Sefe对您的课程提出了一个很好的问题。
您不应让Apartment从House继承。
如果让我们说一个带有属性的类“水果”,则此概念更有意义。然后,您会从“水果”继承一些特定的类,例如“苹果”或“梨”。它们都具有与水果相同的特性,并且具有自己的特性。
要解决您的特定问题:您忘记了一些“;”我删除了继承。 另外,您还没有为列表或Apartment内的属性房屋指定获取或设置。要创建类的变量,请参见上面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;}
}