Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 6 MORE ABOUT CLASSES

An Example of a Computed, Read-Only Property

In most of the examples so far, the property has been associated with a field, and the get and set accessors have referenced that field. However, a property does not have to be associated with a field. In the following example, the get accessor computes the return value.

In the following example code, class RightTriangle represents, not surprisingly, a right triangle.

It has two public fields that represent the lengths of the two right-angle sides of the triangle. These fields can be written to and read from.

The third side is represented by property Hypotenuse, which is a read-only property whose return value is based on the lengths of the other two sides. It isn’t stored in a field. Instead, it computes the correct value, on demand, for the current values of A and B.

Figure 6-11 illustrates read-only property Hypotenuse.

class RightTriangle

 

{

 

public double A = 3;

 

public double B = 4;

 

public double Hypotenuse

// Read-only property

{

 

get{ return Math.Sqrt((A*A)+(B*B)); }

// Calculate return value

}

 

}

 

class Program

 

{

 

static void Main()

 

{

 

RightTriangle c = new RightTriangle(); Console.WriteLine("Hypotenuse: {0}", c.Hypotenuse);

}

}

Figure 6-11. Read-only property Hypotenuse

129

CHAPTER 6 MORE ABOUT CLASSES

Example of Properties and Databases

Another example in which a property is not associated with a field is when the property is associated with a value in a database. In that case, the get accessor makes the appropriate database calls to get the value from the database. The set accessor makes the corresponding calls to the database to set the new value in the database.

For example, the following property is associated with a particular value in some database. The code assumes that there are two other methods in the class to handle the details of the database transactions:

SetValueInDatabase takes an integer parameter and uses it to set a particular field in a record in some database.

GetValueFromDatabase retrieves and returns a particular integer field value from a particular record in some database.

int MyDatabaseValue

 

{

 

set

// Sets integer value in the database

{

 

SetValueInDatabase(value);

}

get // Gets integer value from the database

{

return GetValueFromDatabase();

}

}

Properties vs. Public Fields

As a matter of preferred coding practice, properties are preferred over public fields for several reasons:

Since properties are functional members as opposed to data members, they allow you to process the input and output, which you can’t do with public fields.

The semantics of a compiled variable and a compiled property are different.

The second point has implications when you release an assembly that is accessed by other code. For example, sometimes there’s the temptation is to use a public field rather than a property, with the reasoning that if you ever need to add processing to the data held in the field, you can always change it to a property at a later time. This is true, but if you make that change, you will also have to recompile any other assemblies accessing that field, because the compiled semantics of fields and properties are different. On the other hand, if you had implemented it as a property and just changed its implementation, you wouldn’t need to recompile the other assemblies accessing it.

130

static void Main()
{
class C1
{

CHAPTER 6 MORE ABOUT CLASSES

Automatically Implemented Properties

Because properties are so often associated with backing fields, C# 3.0 added automatically implemented properties, or auto-implemented properties, which allow you to just declare the property, without declaring a backing field. The compiler creates a hidden backing field for you and automatically hooks up the get and set accessors to it.

The important points about auto-implemented properties are the following:

You do not declare the backing field—the compiler allocates the storage for you, based on the type of the property.

You cannot supply the bodies of the accessors—they must be declared simply as semicolons. The get acts as a simple read of the memory, and the set as a simple write.

You cannot access the backing field other than through the accessors. Since you can’t access it any other way, it wouldn’t make sense to have read-only or write-only auto-implemented properties—so they’re not allowed.

The following code shows an example of an automatically implemented property:

← No declared backing field

public int MyValue // Allocates memory

{

 

set;

get;

}

} The bodies of the accessors are declared as semicolons.

class Program

{

Use auto-implemented properties as regular properties.

C1 c = new C1();

Console.WriteLine("MyValue: {0}", c.MyValue);

c.MyValue = 20;

Console.WriteLine("MyValue: {0}", c.MyValue);

}

}

This code produces the following output:

MyValue: 0

MyValue: 20

Besides being convenient, auto-implemented properties allow you to easily insert a property where you might be tempted to declare a public field.

131

CHAPTER 6 MORE ABOUT CLASSES

Static Properties

Properties can also be declared static. Accessors of static properties, like all static members

Cannot access instance members of a class—although they can be accessed by them

Exist regardless of whether there are instances of the class

Must be referenced by the class name, rather than an instance name, when being accessed from outside the class

For example, the following code shows a class with an auto-implemented static property called MyValue. In the first three lines of Main, the property is accessed, even though there are no instances of the class. The last line of Main calls an instance method that accesses the property from inside the class.

class Trivial

 

 

 

{

 

 

 

public static int MyValue { get;

set; }

public void PrintValue()

Accessed from inside the class

{

 

Console.WriteLine("Value from inside: {0}", MyValue);

}

 

 

 

}

 

 

 

class Program

 

 

 

{

Accessed from outside the class

static void Main()

{

 

 

Console.WriteLine("Init Value: {0}", Trivial.MyValue);

Trivial.MyValue = 10;

← Accessed from outside the class

Console.WriteLine("New Value : {0}", Trivial.MyValue);

Trivial tr = new Trivial(); tr.PrintValue();

}

}

Init Value: 0

New Value : 10

Value from inside: 10

132

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