Читайте также:
|
|
Загальні типи (generics) дають змогу при оголошенні класів, структур, методів, інтерфейсів і делегатів не вказувати конкретні типи параметрів. Тип параметра визначить компілятор самостійно в момент оголошення змінної.
Загальний тип подібний до шаблону (template) C++, однак має деякі обмеження.
Утворимо клас з використанням загальних типів.
class CGeneric <TYPE1, TYPE2> { public TYPE1 Field1; public TYPE2 Field2;
public CGeneric (TYPE1 Field1, TYPE2 Field2) { this.Field1 = Field1; this.Field2 = Field2;
}
//інші члени класу
}
Після назви класу розміщено перелік загальних типів, які використовує клас. При оголошенні змінної типу цього класу замість загальних потрібно вказати конкретні типи. Наприклад:
CGeneric<int,int> intVar =
new CGeneric<int,int>(0,1);
CGeneric<bool,bool> boolVar =
new CGeneric< bool,bool >(true,false);
CGeneric<string,float> mixedVar =
new CGeneric<string,float>("Pi",3.14);
Компілятор читає конкретні типи та підставляє їх замість загальних. Наприклад, змінна intVar буде екземпляром класу CGeneric, де поля Field1 та Field2 мають тип int. У цьому випадку можна написати, наприклад, такий код:
int sum = intVar.Field1 + intVar.Field2;
Однак помилковим буде код
float sum = mixedVar.Field1+mixedVar.Field2;
оскільки операція додавання стрічки до числа неозначена.
У межах класу конкретний тип невідомий. Отож потрібно бути обережним з використанням специфічної функціональності конкретних типів і складанням виразів.
Загальні типи корисні за необхідності утворення класів з ідентичною функціональністю, проте різними типами даних. Як приклад, утворимо простий клас, який вміє шукати мінімум і максимум двох значень типу (з означеною операцією порівняння).
class CMinMax <TYPE> { public TYPE Field1; public TYPE Field2;
public CMinMax (TYPE Field1, TYPE Field2) { this.Field1 = Field1; this.Field2 = Field2;
}
public TYPE Min{
get { return Field1 < Field2?
Field1: Field2; }
}
public TYPE Max{
get { return Field1 < Field2?
Field2: Field1; }
}
}
Тепер використаємо клас CMinMax: //оголошення
CMinMax<int> iVar = new CMinMax<int>(0,1); CMinMax<float> fVar = new
CMinMax<float>(0.5,1.71); CMinMax<string> sVar = new
CMinMax<string>("Ab","Cd");
//використання int i = iVar.Min; // i = 0 float f = fVar.Max; // f = 1.71 string s = sVar.Min; // s = "Ab"
Очевидно, що для пошуку мінімуму-максимуму двох значень простіше використати безпосередньо оператор? або статичні функції Min та Max класу Math. Наведений приклад демонструє лише принцип використання загальних типів.
Загальні типи можуть бути корисними і в тих випадках, де задля узагальнення деякої функціональності використовують тип object, а в кожному конкретному випадку він явним чином приводиться до потрібного типу. Оскільки компілятор замість загального типу підставляє заданий, то явного приведення типів можна уникнути. Це дає змогу писати продуктивніші програми. Окрім цього, на противагу використанню типу object з наступним приведенням типу, для загальних типів компілятор здійснює їхню перевірку у момент компіляції. Це зменшує можливість виникнення помилок виконання.
Параметризованими можна оголошувати і структури, інтерфейси та делегати:
//структура
public struct SGeneric <TYPE> { public TYPE Field;
}
//інтерфейс
public interface IGeneric <TYPE> { public TYPE Method();
}
//оголошення делегата
public delegate RESULTTYPE
DGeneric<RESULTTYPE,PARAMTYPE>
(PARAMTYPE aParam);
//використання делегата
DGeneric<double,int> dgen =
new DGeneric<double,int>(ClassA.Ml);
double ml = dgen(l0);
Примітка. Загальні типи введені в.NET Framework 2.
Директиви препроцесора C#
C# містить команди, які впливають на процес компіляції, проте ніколи не транслюються у виконуваний код. Вони називаються директивами препроцесора і починаються з символу #.
Наступна таблиця містить перелік і зміст директив препроцесора.
Приклад |
Зміст |
Директива
#define DEBUG
#undef DEBUG
#if DEBUG //деякі дії #elif WIN64 //деякі дії #else
не |
#error |
&& |
не |
#region #endregion #line |
//деякі дії #endif
#warning забути вилучити попередження" #if DEBUG RELEASE #error "одночасно може бути" #endif #region RegionName //код
#define #undef #if #elif #else #endif #warning |
#endregion #line "File.cs" //деякі дії #line default
Повідомляє компілятору, що існує символ із зазначеним іменем. Повідомляє компілятору, що вже не існує символ із зазначеним іменем. Ці директиви дають вказівку компілятору: компілювати деяку частину коду чи ні. Директива #elif означає else if. Директиви #elif та #else можуть бути пропущеними..NET надає альтернативу #if із використанням атрибута
Conditional.
Компілятор виводить користувачу текст, розташований після директиви. Компіляція буде продовжена. Компілятор виводить користувачу текст, розташований після директиви. Компіляція буде припинена.
Редактори тексту можуть використати ці директиви для кращого розташування коду на екрані, у тім числі згорнути/розгорнути цей код. Використовують для зміни інформації про ім'я файла та номер стрічки, яка виводиться компілятором у попередженнях і повідомленнях про помилки.
Дата добавления: 2015-10-31; просмотров: 136 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Група Операції | | | Простори імен |