代表家庭和人民
本文关键字:家庭 | 更新日期: 2023-09-27 18:13:54
在c++中我可以这样做
class Person
{
House * myhouse;
}
class House
{
std::vector<Person*> members;
}
如何在c#中做类似的事情?
public class Person
{
public House MyHouse { get; set; }
}
public class House
{
public List<Person> Members { get; private set; }
public House()
{
this.Members = new List<Person>();
}
}
这里我使用属性,特别是自动属性,而不是字段。这既是为了更干净,将字段公开给外部世界通常不如公开属性干净,也是因为我可以通过这种方式控制人们如何访问属性进行读和写。在这个例子中,属性Members对于读是公有的,但是对于写是私有的,我在构造函数中初始化了它。
在c#中没有对象在堆栈中分配的概念,对象总是在堆中分配的。
这意味着类总是引用类型,并且List类型的变量是对List类型对象的引用,就像c++中的指针一样。因此,您需要使用new操作符来分配它,否则默认值将为null。
当然,正如你所知道的,在c#中有垃圾收集器,所以你不需要删除对象。
c#中也有值类型,像int、float、double和struct这样的基本类型都是值类型,它们的工作方式确实不同。
数组和字符串仍然是引用类型(类)。
还需要注意的是,c#类的字段在构造函数中默认初始化为0,你能想到的每种类型都将初始化为0,因此,指针将为null,浮点数将为0.0f,结构体将是所有字段设置为0的结构体。就像c中的callloc。
然而,还有另一种完全不同的方法。我们可以使用基类Collection,并使MyHouse属性完全透明和安全:我们在更改集合时设置它,这种技术经常使用。 public class Person
{
// This field is internal, it means that all classes in the same module (in the same dll for example) can access to this field.
// This keyword was introduced for the same reason that the "friend" keyword exists in C++.
// We need this internal so we can modify it from House class.
internal House house;
public House MyHouse
{
get { return this.house; }
}
}
public class House :
System.Collections.ObjectModel.Collection<Person>
{
// We shadow the base member, this is faster than default implementation, O(1).
public new bool Contains(Person person)
{
return person != null && person.house == this;
}
protected override void RemoveItem(int index)
{
Person person = this[index];
base.RemoveItem(index);
person.house = null;
}
protected override void SetItem(int index, Person item)
{
if (item == null)
throw new ArgumentNullException("Person is null");
if (item.house != null)
throw new InvalidOperationException("Person already owned by another house");
Person old = this[index];
base.SetItem(index, item);
old.house = null;
item.house = this;
}
protected override void InsertItem(int index, Person item)
{
if (item == null)
throw new ArgumentNullException("Person is null");
if (item.house != null)
throw new InvalidOperationException("Person already owned by another house");
base.InsertItem(index, item);
item.house = this;
}
protected override void ClearItems()
{
foreach (Person person in this)
{
person.house = null;
}
base.ClearItems();
}
}
class Person
{
House myhouse;
}
class House
{
List<Person> members = new List<Person>;
}