2012-06-06 37 views
3

考虑类:C#属性隐藏实例变量还是更深层次?

public class foo 
{ 
    public object newObject 
    { 
     get 
     { 
      return new object(); 
     } 
    } 
} 

根据MSDN:

属性是成员提供了一个灵活的机制来读,写 或计算私有字段的值。属性可以使用 就好像它们是公共数据成员一样,但它们实际上是特殊的 称为访问器的方法。这使得数据可以很容易地访问

和:

属性使类揭露获取和 设定值的公开方式,而隐藏实现或验证码。

获取属性访问器用于返回属性值,并使用 集访问器来分配新值。这些访问器可以有不同的访问级别。有关更多信息,请参阅访问者 辅助功能。

value关键字用于定义 集索引器分配的值。

不执行set方法的属性是只读的。同时仍然提供方法的安全性和灵活性。

这是否意味着在某个时间点newObject属性的值有一个对返回的新对象的引用?

编辑物业

EDIT2也只读去除想澄清一下,这不是一个属性的最佳利用,但其做了尝试,更有效地说明了这个问题。

+3

'readonly'修饰符在属性声明中无效。 – Ani

回答

10

您在对该属性的每次访问中返回一个新对象,这不是属性的预期行为。相反,您应该每次都返回相同的值(例如,存储在字段中的值)。 属性获取器是返回值为的方法的简单语法化语法。您的代码编译成这样的事(编译器创建与get_前缀属性名吸气,然后发出为IL):

public class foo 
{ 
    public object get_newObject() 
    { 
     return new object(); 
    } 
} 

每次调用吸气那foo没有将创建新的对象了解或有权访问。

这是否意味着在某个时间点newObject属性的值有一个对返回的新对象的引用?

No.使用支持字段


性质:

class Foo { 

    readonly Object bar = new Object(); 

    public Object Bar { get { return this.bar; } } 

} 

使用自动属性:

class Foo { 

    public Foo() { 
    Bar = new Object(); 
    } 

    public Object Bar { get; private set; } 

} 

一个属性是使用相同的容易的语法作为公共字段访问。但是,通过使用属性,您可以将代码添加到getter和setter中,从而允许您在getter中执行延迟加载或在setter中进行验证(以及更多)。

+0

感谢关于只读的观点。我已将其删除。我知道这不是预期的行为,但我对基础架构感到好奇。我明白,每次访问时都会得到一个新的值,但这是否意味着类的实例从不知道要返回的值? –

+0

+1可能会添加一个小站点,说明为什么属性是C#的语言特性(在某些其他语言中,具有数千个方法(如'float GetBla()'和'void SetBla(float value)')。 –

0

不完全。属性只是语法糖,因此您不必编写访问器方法(如Java)。

所以这样的:

private int _myInteger; 
public int MyInteger 
{ 
    get { return _myInteger; } 
    set { _myInteger = value; } 
} 

是equivilant这样:

private int _myInteger; 
public int GetMyInteger() 
{ 
    return _myInteger; 
} 

public void SetMyInteger(int value) 
{ 
    _myInteger = value; 
} 

,并获取与此比较好,这也是equivilant:

public int MyInteger { get; set; } 
1

引擎盖下,你的属性只会调用一个名为get_newObject()的函数,如下所示:

public object get_newObject() 
{ 
    return new object(); 
} 

由于是这种情况,每次调用它时都会返回一个新的对象。

如果你想保留的对象的引用,那么我会建议创建一个私有字段来保存数据,并具有属性访问该字段,就像这样:

private object myObject; 
public object newObject 
{ 
    if(myObject == null) 
    { 
     myObject = new object(); 
    } 
    return myObject; 
} 

因为你的财产没有按” t定义集合,并且您的字段是私有的,newObject基本上不包含在包含类中。

1

C#中的属性是“语法糖”。 get区块内的代码实际上被置入隐藏的get_PropertyName()方法中,并且set区块变为隐藏的set_PropertyName()方法。在你的代码的情况下,下面的方法将被创建:

public object get_newObject() 
{ 
    return new object(); 
} 

你可以看到这些隐藏的方法,如果你查看编译的程序集使用反射或ILDASM。

使用该属性时,C#编译器会将您的属性的任何“get”访问转换为get_newObject()方法的调用。举个例子:

如果你写了以下内容:

var foo = new foo(); 
var aNewObject = foo.newObject; 

,编译器将进行转换的:

var foo = new foo(); 
var aNewObject = foo.get_newObject(); 

所以,在回答您的其他问题,新创建的对象当某人“获取”该属性时不会将其存储在您的foo实例中,则调用者每次只会获取一个新对象。

相关问题