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

CHAPTER 7 CLASSES AND INHERITANCE

Sealed Classes

In the previous section, you saw that an abstract class must be used as a base class—it cannot be instantiated as a stand-alone class object. The opposite is true of a sealed class.

A sealed class can be instantiated only as a stand-alone class object—it cannot be used as a base class.

A sealed class is labeled with the sealed modifier.

For example, the following class is a sealed class. Any attempt to use it as the base class of another class will produce a compile error.

Keyword

sealed class MyClass

{

...

}

195

CHAPTER 7 CLASSES AND INHERITANCE

Static Classes

A static class is a class where all the members are static. Static classes are used to group data and functions that are not affected by instance data. A common use of a static class might be to create a math library containing sets of mathematical methods and values.

The important things to know about static classes are the following:

The class itself must be marked static.

All the members of the class must be static.

The class can have a static constructor, but it cannot have an instance constructor, since you cannot create an instance of the class.

Static classes are implicitly sealed. That is, you cannot inherit from a static class.

You access the members of a static class just as you would access any static member, by using the class name and the member name.

The following code shows an example of a static class:

Class must be marked static

 

 

 

 

static public class MyMath

 

 

 

{

 

 

 

 

 

 

 

public static float PI = 3.14f;

 

 

 

public static bool IsOdd(int x)

 

 

 

 

 

{ return x % 2 == 1; }

 

 

 

Members must be static

 

 

 

 

 

 

 

 

 

public static int Times2(int x)

 

 

 

}

 

 

 

{ return 2 * x; }

 

 

 

 

 

 

 

 

 

 

class Program

 

 

 

 

{

 

 

 

 

 

 

 

static void Main( )

Use class name and member name.

{

 

 

 

 

int val = 3;

 

 

 

Console.WriteLine("{0} is odd is {1}.", val,

MyMath.IsOdd(val));

Console.WriteLine("{0} * 2 = {1}.",

val,

MyMath.Times2(val));

}

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

This code produces the following output:

3 is odd is True.

3 * 2 = 6.

196

CHAPTER 7 CLASSES AND INHERITANCE

Extension Methods

So far in this text, every method you’ve seen has been associated with the class in which it is declared. The extension method feature introduced in C# 3.0 extends that boundary, allowing you to write methods associated with classes other than the class in which they are declared.

To see how you might use this feature, take a look at the following code. It contains class MyData, which stores three values of type double, and contains a constructor and a method called Sum, which returns the sum of the three stored values.

class MyData

 

 

{

 

 

private double

D1;

// Fields

private double

D2;

 

private double

D3;

 

public MyData(double d1, double d2, double d3)

// Constructor

{

 

 

D1 = d1; D2

= d2; D3 = d3;

 

}

 

 

public double Sum()

// Method Sum

{

 

 

return D1 +

D2 + D3;

 

}

 

 

}

 

 

This is a pretty limited class, but suppose it would be more useful if it contained another method, which returned the average of the three data points. With what you know so far about classes, there are several ways you might implement the additional functionality:

If you have the source code and can modify the class, you could, of course, just add the new method to the class.

If, however, you can’t modify the class—for example, if the class is in a third-party class library— then, as long as it isn’t sealed, you could use it as a base class and implement the additional method in a class derived from it.

If, however, you don’t have access to the code or the class is sealed or there is some other design reason that neither of these solutions will work, then you will have to write a method in another class that uses the publicly available members of the class.

197

CHAPTER 7 CLASSES AND INHERITANCE

For example, you might write a class like the one in the following code. The code contains a static class called ExtendMyData, which contains a static method called Average, which implements the additional functionality. Notice that the method takes an instance of MyData as a parameter.

static class ExtendMyData

Instance of MyData class

{

 

 

 

 

 

public static double Average( MyData md )

 

 

{

 

 

 

 

 

 

 

 

return md.Sum() / 3;

 

 

 

 

 

 

}

 

 

 

 

 

 

} Use the instance of MyData.

 

 

 

 

 

 

class Program

 

 

 

 

 

 

{

 

 

 

 

 

 

 

static void Main()

 

 

 

 

Instance of MyData

{

 

 

 

 

 

 

MyData md = new MyData(3, 4, 5);

 

Console.WriteLine("Average: {0}", ExtendMyData.Average(md));

}

 

 

 

 

 

 

}

 

 

 

 

 

Call the static method.

This code produces the following output:

Average: 4

Although this is a perfectly fine solution, it would be more elegant if you could call the method on the class instance itself, rather than creating an instance of another class to act on it. The following two lines of code illustrate the difference. The first uses the method just shown—invoking a static method on an instance of another class. The second shows the form we would like to use—invoking an instance method on the object itself.

ExtendMyData.Average( md )

//

Static invocation form

md.Average();

//

Instance invocation form

Extension methods allow you to use the second form, even though the first form would be the normal way of writing the invocation.

198

CHAPTER 7 CLASSES AND INHERITANCE

By making a small change in the declaration of method Average, you can use the instance invocation form. The change you need to make is to add the keyword this before the type name in the parameter declaration as shown following. Adding the this keyword to the first parameter of the static method of the static class changes it from a regular method of class ExtendMyData into an extension method of class MyData. You can now use both invocation forms.

Must be a static class

 

 

 

 

 

static class ExtendMyData

 

 

 

{ Must be public and static

Keyword and type

 

 

 

 

 

 

public static double Average( this MyData md )

{

...

)

}

The important requirements for an extension method are the following:

The class in which the extension method is declared must also be declared static.

The extension method itself must be declared static.

The extension method must contain as its first parameter type the keyword this, followed by the name of the class it is extending.

Figure 7-22 illustrates the structure of an extension method.

Figure 7-22. The structure of an extension method

199

CHAPTER 7 CLASSES AND INHERITANCE

The following code shows a full program, including class MyData and extension method Average declared in class ExtendMyData. Notice that method Average is invoked exactly as if it were an instance member of MyData! Figure 7-22 illustrates the code. Classes MyData and ExtendMyData together act like the desired class, with three methods.

namespace ExtensionMethods

{

sealed class MyData

{

private double D1, D2, D3;

public MyData(double d1, double d2, double d3) { D1 = d1; D2 = d2; D3 = d3; }

public double Sum() { return D1 + D2 + D3; }

}

 

 

 

 

 

 

static class ExtendMyData

Keyword and type

{

 

 

 

public static double Average(this MyData md)

{

 

 

 

 

 

 

Declared static

 

 

 

 

 

}

return md.Sum() / 3;

 

 

 

 

 

 

 

 

 

 

 

}

 

 

 

 

 

 

class Program

 

 

 

 

 

{

 

 

 

 

 

 

static void Main()

 

 

 

 

 

{

MyData md = new MyData(3, 4, 5);

 

 

Console.WriteLine("Sum:

 

{0}", md.Sum());

 

Console.WriteLine("Average: {0}", md.Average());

}

 

 

 

 

 

}

Invoke as an instance member of the class

}

This code produces the following output:

Sum: 12

Average: 4

200

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