我从C#开始,我有一个问题。
说我有一个对象:
Person
和Person上的一个名为Cat的属性:
Person.Cat
如果我这样做:
Cat cat = new Cat(stuff);
cat.Name = "Alan";
Person.Cat = cat;
Cat是猫的直接参考吗? 如果我这样做:
Person.Cat.Name = "John";
猫的名字会是“约翰”吗?
因为我觉得我之前尝试过这样的事情,并且我得到了NullReferenceException或类似的东西。
答案 0 :(得分:5)
如果'cat'是一个类,即一个引用类型,那么该引用的副本将存储在person.Cat中。这意味着对'cat'属性的更改将反映在person.Cat中。但是,由于它是原始引用的副本,因此行为如下:
Cat cat = new Cat(stuff);
cat.Name = "Alan";
Person.Cat = cat;
cat.Name = "Will"; //Person.Cat.Name is now "Will"
cat = new Cat(stuff);
cat.Name = "Greg";
// Person.Cat is still named "Will".
// The original reference now points to a different object on the heap than does Person.Cat.
如果Cat是一个值类型,那么副本是在赋值时生成的,一个中的更改不会反映在另一个中(当然,一个struct可以有一个引用类型属性或公共字段,但你明白了)。
答案 1 :(得分:1)
这是正确的,假设您的完整代码是这样的:
// Person class.
public class Person {
// Automatic property.
public Cat Cat { get; set; }
}
// Cat class (not a struct!).
public class Cat {
// Automatic property.
public string Name { get; set; }
}
在这种情况下,访问myPerson.Cat
将直接引用该对象。您可以在其上调用方法,访问其属性,将其传递给接受Cat
参数的方法,无论您喜欢什么。
但是,在这种情况下,您无法确定myPerson.Cat
属性不是null
。任何代码都可以将其设置为Cat
或null
类型的任何对象。如果某些内容已将其设置为null
并且您尝试访问myPerson.Cat.Name
,则会获得NullReferenceException
。
为了避免出现这些异常,在使用之前,应始终通过if (myPerson.Cat != null) { ... }
等显式检查验证该属性是否为null。如果您确定肯定它永远不会null
,并且没有任何内容可以违反此假设,则可以跳过此步骤。您可能希望使用code contracts来确保以后在您对该语言更加满意的时候这样做。
答案 2 :(得分:0)
Cat是猫的直接参考吗?
是。例如:
var cat = new Cat(stuff);
cat.Name = "Alan";
Person.Cat = cat;
cat.Name = "George";
var nowCalledGeorge = Person.Cat.Name;
这个问题的答案
猫的名字会是“约翰”吗?
是的。