C#属性引用类型?

时间:2010-08-07 03:42:57

标签: c#

我从C#开始,我有一个问题。

说我有一个对象:

Person

和Person上的一个名为Cat的属性:

Person.Cat

如果我这样做:

Cat cat = new Cat(stuff);
cat.Name = "Alan";
Person.Cat = cat;

Cat是猫的直接参考吗? 如果我这样做:

Person.Cat.Name = "John";

猫的名字会是“约翰”吗?

因为我觉得我之前尝试过这样的事情,并且我得到了NullReferenceException或类似的东西。

3 个答案:

答案 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。任何代码都可以将其设置为Catnull类型的任何对象。如果某些内容已将其设置为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;

这个问题的答案

  

猫的名字会是“约翰”吗?

是的。