Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Использование переменных обобщенного типа в качестве операндов




И, наконец, замечу, что немало трудностей несет в себе использование операторов с операндами обобщенного типа. C# умеет интерпретировать операторы (например +, -, * и /), применяемые к элементарным типам. Но эти операторы нельзя использовать с переменными обобщенного типа, потому что во время компиляции компилятор не знает их тип. Получается, что вы не сможете написать математический алгоритм для произвольных числовых типов данных. Я написал следующий обобщенный метод.

 

private static T Sum<T>(T num) where T : struct

{

T sum = default(T);

for (T n = default(T); n < num; n++)

sum += n; return sum;

}

 

Я также сделал все возможное, чтобы он скомпилировался: определил ограничение struct для T и использовал default(T), чтобы sum и n инициализировались нулем. Но при компиляции кода появились три сообщения об ошибке:

1. ошибка CS0019: оператор «<» нельзя применять к операндам типа T и T

2. ошибка CS0023: оператор «++» нельзя применять к операнду типа T

3. ошибка CS0019: оператор «+=» нельзя применять к операндам типа T и T

Это существенно ограничивает поддержку обобщений в CLR-среде, и многие разработчики испытали глубокое разочарование. Многие пытались создать методы, призванные обойти это ограничение с помощью отражения (главу глава 22), перегрузку оператора и т. п. Но все эти решения сильно снижают производительность или ухудшают читабельность кода.

=====================

Общие (или параметризованные) типы (generics) позволяют при описании классов, структур, методов и интерфейсов использовать параметризованные параметры (не указывать тип параметра в момент написания кода). Тип параметра определяется в момент объявления переменной соответствующего типа. Таким образом можно создать некоторый общий элемент, тип который можно использовать в дальнейшем для данных различных типов. Программисты на C++ могут углядеть с общих типах сходство с шаблонами (templates), в чем-то эта аналогия будет верна, но тут существуют некоторые ограничения.

Создадим класс, используя общие типы:

class Generics<TYPE1, TYPE2>

{

private TYPE1 mVar1;

private TYPE2 mVar2;

public Generics(TYPE1 Var1, TYPE2 Var2)

{

this.mVar1 = Var1;

this.mVar2 = Var2;

}

public string ToStringFunction(string Delemiter)

{

return this.mVar1.ToString() + Delemiter + this.mVar2.ToString();

}

public TYPE1 Variable1

{

get

{

return this.mVar1;

}

set

{

this.mVar1 = value;

}

}

public TYPE2 Variable2

{

get

{

return this.mVar2;

}

set

{

this.mVar2 = value;

}

}

}

 

Как видно из примера, для того чтобы использовать общие типы нужно после объявления класса указать параметризованные типы: Generics<TYPE1, TYPE2> объявляет класс с двумя параметризованными типами. Теперь используем написанный класс:

 

// объявление

Generics<string, string> strGeneric = new Generics<string, string>("Hello", "world");

Generics<int, int> intGeneric = new Generics<int, int>(1, 2);

Generics<string, int> strintGeneric = new Generics<string, int>("Three", 3);

int intSum;

string strSum;

// использование

intSum = intGeneric.Variable1 + intGeneric.Variable2;

strSum = strintGeneric.Variable1 + " " + strintGeneric.Variable2.ToString();

MessageBox.Show("\nstrGeneric:\n" + strGeneric.Variable1 + " " + strGeneric.Variable2 +

"\n\nintGeneric sum:\n" + intSum.ToString() +

"\n\nstrintGeneric sum:\n" + strSum.ToString());

 

Таким образом, очевидно, что создан класс который можно использовать с параметрами различных типов, которые устанавливаются в момент объявления класса. Аналогичным образом можно объявить структуру или интерфейс:

 

public struct GenericStruct<TYPE>

{

public TYPE someField;

}

public interface IGeneric<TYPE>

{

TYPE SomeMethod();

TYPE AnotherMethod();

}

 

Более того, параметризованные типы могут быть использованы при объявлении делегатов функций. Продемонстрирую эту возможность используя объявленный выше класс Generics.

 

// Объявляем делегат

public delegate DELEGATETYPE GenericDelegate<DELEGATETYPE, PARAMTYPE> (PARAMTYPE Param);

// используем делегат

Generics<string, string> strGeneric = new Generics<string, string>("Hello", "world");

GenericDelegate<string, string> genDelegate =

new GenericDelegate<string, string>(strGeneric.ToStringFunction);

// вызов делагата

MessageBox.Show(genDelegate(" my "));

 


Поделиться:

Дата добавления: 2015-04-21; просмотров: 334; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.006 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты