2010-08-07 84 views
3

我开始在C#中,我有一个问题。C#属性引用类型?

说我有一个对象:

Person 

,并呼吁猫对人的属性:

Person.Cat 

如果我做的:

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

是猫的直接引用猫? 如果我做的:

Person.Cat.Name = "John"; 

威尔猫的名称是 “约翰”?

因为我觉得我尝试过做这样的事情,和我的NullReferenceException或类似的东西。

+0

你试过了会发生什么? – ChaosPandion 2010-08-07 03:44:26

+0

这与XNA无关。如果可能,您应该删除该标签。 – Rich 2010-08-07 03:45:43

+0

您的'NullReferenceException'可能发生是因为您的程序尚未为'Person.Cat'分配一个值。 – 2010-08-07 03:49:11

回答

5

如果“猫”是一个类,即,引用类型,比基准的副本将被存储在person.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. 

如果猫是值类型,则副本后分配制成,在一个变化将不会在其他反映(当然,一个结构可以有一个引用类型属性或公共字段,但你明白了)。

+0

另请注意,结构是值类型,因此对于这些结构,将创建副本而不是参考。 – 2010-08-07 04:04:45

0

是猫的直接引用猫吗?

是的。例如:

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

所以,这个问题的答案

威尔猫的名称是 “约翰”?

是肯定的。

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

为了避免让这些例外情况,你应该总是验证属性不为null,通过像if (myPerson.Cat != null) { ... }直接检查使用它之前。如果你知道肯定它不能是null,并且没有任何东西可以违反这个假设,你可以跳过这一步。您可能需要考虑使用code contracts以确保在将来您更熟悉该语言。