Как правильно писать тесты 46 Цикл разработки 46 Структура проекта с тестами 51 Утверждения (Asserts) 52 Утверждения в форме ограничений 54 Категории 56

Вид материалаТесты

Содержание


Создание обобщенных методов
Подобный материал:
1   ...   36   37   38   39   40   41   42   43   ...   47

Тип List




Подобно необобщенным классам, обобщенные классы являются объектами, размещаемыми в динамической памяти, поэтому для них следует использовать new со всеми необходимыми аргументами конструктора. Кроме того, вы должны указать типы, замещающие параметры, определенные обобщенным типом. Так, для System.Collections.Generic.List требуется указать одно значение, задающее вид элемента, с которым будет функционировать List. Например, чтобы создать три объекта List<> для хранения целых чисел, объектов SportsCar и объектов Person, вы должны записать следующее.


static void Main(string[] args)

{

// Создается List для хранения целых чисел.

List myInts = new List();


// Создается List для хранения объектов SportsCar.

List myCars = new List();


// Создается List для хранения объектов Person.

List
myPeople = new List
();

}


В этот момент вы можете поинтересоваться, что же на самом деле становится значением заполнителя. Открыв окно определения программного кода в Visual Studio, вы увидите, что везде в определении типа List используется заполнитель T. Ниже показана часть соответствующего листинга.


// Часть листинга для типа List.

namespace System.Collections.Generic

{

public class List :

IList, ICollection, IEnumerable,

IList, ICollection, IEnumerable

{

...

public void Add(T item);

public IList AsReadOnly();

public int BinarySearch(T item);

public bool Contains(T item);

public void CopyTo(T[] array);

public int FindIndex(System.Predicate match);

public T FindLast(System.Predicate match);

public bool Remove(T item);

public int RemoveAll(System.Predicate match);

public T[] ToArray();

public bool TrueForAll(System.Predicate match);

public T this[int index] { get; set; }

...

}

}


Когда вы создаете тип List и указываете для него SportsCar, это эквивалентно следующему определению типа List.


namespace System.Collections.Generic

{

public class List :

IList, ICollection, IEnumerable,

IList, ICollection, IEnumerable

{

...

public void Add(SportsCar item);

public IList AsReadOnly();

public int BinarySearch(SportsCar item);

public bool Contains(SportsCar item);

public void CopyTo(SportsCar[] array);

public int FindIndex(System.Predicate match);

public SportsCar FindLast(System.Predicate match);

public bool Remove(SportsCar item);

public int RemoveAll(System.Predicate match);

public SportsCar [] ToArray();

public bool TrueForAll(System.Predicate match);

public SportsCar this[int index] { get; set; }

...

}

}


Конечно, когда вы создаете обобщенный List, нельзя сказать, что компилятор буквально создает совершенно новую реализацию типа List. Он обращается только к тем членам обобщенного типа, которые вы вызываете фактически.


Создание обобщенных методов




Чтобы научиться интегрировать обобщения в проекты, мы начнем с простого примера обычной подпрограммы свопинга. Целью этого примера является построение метода обмена, который сможет работать с любыми типами данных (характеризуемыми значениями или ссылками), используя для этого один параметр типа. В силу самой природы алгоритмов свопинга входные параметры будут посылаться по ссылке (с помощью ключевого слова C# ref). Вот соответствующая полная реализация.


// Этот метод переставляет любые два элемента,

// определенные параметром типа .

static void Swap(ref T a, ref T b)

{

Console.WriteLine("Методу Swap() передано {0}",

typeof(T));

T temp;

temp = a;

a = b;

b = temp;

}


Обратите внимание на то, что обобщенный метод определяется с помощью указания параметра типа, размещаемого после имени метода, но перед списком параметров. Здесь вы заявляете, что метод Swap() может работать с любыми двумя параметрами типа . Просто для информации вы выводите имя типа соответствующего заменителя на консоль с помощью оператора C# typeof(). Теперь рассмотрите следующий метод Main(), в котором происходит обмен между целочисленными и строковыми типами.


static void Main(string[] args)

{

Console.WriteLine("***** Забавы с обобщениями *****\n");


// Обмен между двумя целыми.

int a = 10, b = 90;

Console.WriteLine("До обмена: {0}, {1}", a, b);

Swap(ref a, ref b);

Console.WriteLine("После обмена: {0}, {1}", a, b);

Console.WriteLine();


// Обмен между двумя строками.

string s1 = "Hello", s2 = "There";

Console.WriteLine("До обмена: {0} {1}!", s1, s2);

Swap(ref s1, ref s2);

Console.WriteLine("После обмена: {0} {1}!", s1, s2);

Console.ReadLine();

}