Читайте также:
|
|
В языке C# возможно разбиение определения класса, структуры или интерфейса между двумя или больше исходными файлами. Каждый исходный файл содержит свою часть определения класса и все такие части собираются во время компиляции.
Есть несколько ситуаций, когда удачно разбить определение класса на несколько
1. При работе над большим проектом, разбиение класса на несколько файлов позволяет нескольким программистам работать над ним одновременно.
2. При работе с автоматически генерируемыми исходниками, код может быть добавлен в класс без необходимости пересоздавать исходник. Visual Studio использует этот подход при создании компонентов Windows Forms, веб-сервисов и т.д. Возможно создать код, который использует эти классы файлов без необходимости редактировать файлы, которые создает Visual Studio.
Для такого разбития класса используется модификатор partial.
All the parts must have the same accessibility, such as public, private, and so on.
Если какая-либо из частей объявлена абстрактной, то весь тип будет считаться абстрактным. Если какая-либо из частей объявлена sealed, то весь тип будет считаться sealed. Если какая-либо из частей объявляет базовый тип, то весь тип будет наследовать данный класс. Модификатор partial нельзя использовать для объявлений делегата или перечисления.
23. Делегаты и события в языке C#. Механизм вызова событий.
Делегаты и события в языке C#
An event is a member that enables a class or object to provide notifications. An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.
Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event is not abstract and does not declare accessors). The field stores a reference to a delegate that represents the event handlers that have been added to the event. If no event handles are present, the field is null.
public event EventHandler Changed;
A delegate type represents references to methods with a particular parameter list and return type. Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.
The following example declares and uses a delegate type named Function.
using System;
delegate double Function(double x);
class Multiplier
{
double factor;
public Multiplier(double factor) {
this.factor = factor;
}
public double Multiply(double x) {
return x * factor;
}
}
class Test
{
static double Square(double x) {
return x * x;
}
static double[] Apply(double[] a, Function f) {
double[] result = new double[a.Length];
for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
return result;
}
static void Main() {
double[] a = {0.0, 0.5, 1.0};
double[] squares = Apply(a, Square);
double[] sines = Apply(a, Math.Sin);
Multiplier m = new Multiplier(2.0);
double[] doubles = Apply(a, m.Multiply);
}
}
An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. In the Main method, Apply is used to apply three different functions to a double[].
A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.
Delegates can also be created using anonymous functions, which are “inline methods” that are created on the fly. Anonymous functions can see the local variables of the sourrounding methods. Thus, the multiplier example above can be written more easily without using a Multiplier class:
double[] doubles = Apply(a, (double x) => x * 2.0);
An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.
Delegates enable scenarios that other languages—such as C++, Pascal, and Modula—have addressed with function pointers. Unlike C++ function pointers, however, delegates are fully object oriented, and unlike C++ pointers to member functions, delegates encapsulate both an object instance and a method.
A delegate declaration defines a class that is derived from the class System.Delegate. A delegate instance encapsulates an invocation list, which is a list of one or more methods, each of which is referred to as a callable entity. For instance methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Invoking a delegate instance with an appropriate set of arguments causes each of the delegate’s callable entities to be invoked with the given set of arguments. Delegates perfectly suit for “anonymous” invocation.
Дата добавления: 2015-11-16; просмотров: 63 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Конструкторы и деструкторы | | | Механизм вызова событий |