Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# 2008 Step by Step.pdf
Скачиваний:
27
Добавлен:
25.03.2016
Размер:
14 Мб
Скачать
☆

282

Part III Creating Components

Properties and Field Names: A Warning

Although it is a commonly accepted practice to give properties and private fields the

same name that differs only in the case of the initial letter, you should be aware of one drawback. Examine the following code, which implements a class named Employee. The employeeID field is private, but the EmployeeID property provides pubic access to this

field.

class Employee

{

private int employeeID;

public int EmployeeID;

{

get { return this.EmployeeID; } set { this.EmployeeID = value; }

}

This code will compile perfectly well, but it results in a program raising a StackOverflowException whenever the EmployeeID property is accessed. This is because

the get and set accessors reference the property (uppercase E) rather than the private field (lowercase e), which causes an endless recursive loop that eventually causes the process to exhaust the available memory. This sort of bug is very difficult to spot!

Understanding the Property Restrictions

Properties look, act, and feel like fields. However, they are not true fields, and certain restrictions apply to them:

You can assign a value through a property of a structure or class only after the structure or class has been initialized. The following code example is illegal, as the location variable has not been initialized (by using new):

ScreenPosition location;

location.X = 40; // compile-time error, location not assigned

Note This might seem trivial, but if X were a field rather than a property, the code would be legal. What this really means is that there are some differences between fields and properties. You should define structures and classes by using properties from the start, rather than by using fields that you later migrate to properties—code that uses your classes and structures might no longer work after you change fields into properties. We will return to this matter in the section “Generating Automatic Properties” later in this chapter.

Chapter 15 Implementing Properties to Access Fields

283

You can’t use a property as a ref or an out argument to a method (although you can use a writable field as a ref or an out argument). This makes sense because the property doesn’t really point to a memory location but rather to an accessor method. For example:

MyMethod(ref location.X); // compile-time error

A property can contain at most one get accessor and one set accessor. A property cannot contain other methods, fields, or properties.

The get and set accessors cannot take any parameters. The data being assigned is passed to the set accessor automatically by using the value variable.

You can’t declare const properties. For example:

const int X { get { ... } set { ... } } // compile-time error

Using Properties Appropriately

Properties are a powerful feature with a clean, fieldlike syntax. Used in the correct manner, properties help to make code easier to understand and maintain. However, they are no substitute for careful object-oriented design that focuses on the behavior of objects rather than on the properties of objects. Accessing private fields through regular methods or through properties does not, by itself, make your code well-

designed. For example, a bank account holds a balance. You might therefore be tempted to create a Balance property on a BankAccount class, like this:

class BankAccount

{

...

public money Balance

{

get { ... } set { ... }

}

private money balance;

}

This would be a poor design. It fails to represent the functionality required when withdrawing money from and depositing money into an account. (If you know of a bank that allows you to set the balance of your account directly without depositing money, please let me know!) When you’re programming, try to express the problem you are solving in the solution and don’t get lost in a mass of low-level syntax:

class BankAccount

{

...

public money Balance { get { ... } } public void Deposit(money amount) { ... } public bool Withdraw(money amount) { ... } private money balance;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]