Читаем Интернет-журнал "Домашняя лаборатория", 2007 №9 полностью

Давайте рассмотрим еще один тестовый пример. В класс Testing включена группа перегруженных методов OLoad с одним и двумя аргументами. Вот эти методы-.

/// 

/// Группа перегруженных методов OLoad

/// с одним или двумя аргументами арифметического типа.

/// Если фактический аргумент один, то будет вызван один из

/// методов, наиболее близко подходящий по типу аргумента.

/// При вызове метода с двумя аргументами возможен

/// конфликт выбора подходящего метода, приводящий

/// к ошибке периода компиляции.

/// 

void OLoad(float par)

}

     Console.WriteLine("float value {0}", par);

///

/// Перегруженный метод OLoad с одним параметром типа long

/// 

/// 

void OLoad(long par)

{

      Console.WriteLine("long value {0}", par);

}

/// 

/// Перегруженный метод OLoad с одним параметром типа ulong

/// 

/// 

void OLoad(ulong par)

{

       Console.WriteLine("ulong value {0}", par);

}

/// 

/// Перегруженный метод OLoad с одним параметром типа double

/// 

/// 

void OLoad(double par)

{

      Console.WriteLine("double value {0}", par);

}

/// 

/// Перегруженный метод OLoad с двумя параметрами типа long и long

/// 

/// 

///  void OLoad(long par1, long par2)

{

      Console.WriteLine("long par1 {0}, long par2 {1}", par1, par2);

}

/// 

/// Перегруженный метод OLoad с двумя параметрами типа

/// double и double

/// 

/// 

///

void OLoad(double par1, double par2)

{

       Console.WriteLine("double par1 {0}, double par2 {1}",par1, par2);

}

/// 

/// Перегруженный метод OLoad с двумя параметрами типа

/// int и float

/// 

///

/// void OLoad(int par1, float par2)

{

       Console.WriteLine("int par1 {0}, float par2 {1}",par1, par2);

}

Все эти методы устроены достаточно просто. Они сообщают информацию о типе и значении переданных аргументов. Вот тестирующая процедура, вызывающая метод OLoad с разным числом и типами аргументов:

/// 

/// Вызов перегруженного метода OLoad. В зависимости от

/// типа и числа аргументов вызывается один из методов группы.

/// 

public void OLoadTest ()

{

      OLoad(x); OLoad(ux);

      OLoad(y); OLoad(dy);

      // OLoad(x,ux);

      // conflict: (int, float) и (long,long)

      OLoad(x,(float)ux);

      OLoad (y,dy); OLoad (x, dy);

}

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

Рис. 4.2.Вывод на печать результатов теста OLoadTest

Прежде чем посмотреть на результаты работы тестирующей процедуры, попробуйте понять, какой из перегруженных методов вызывается для каждого из вызовов. В случае каких-либо сомнений используйте схему, приведенную на 4.1.

Приведу все-таки некоторые комментарии. При первом вызове метода тип источника — int, а тип аргумента у четырех возможных реализаций соответственно float, long, ulong, double. Явного соответствия нет, поэтому нужно искать самый короткий путь на схеме. Так как не существует неявного преобразования из типа int в тип ulong (на диаграмме нет пути), то остаются возможными три реализации. Но путь из int в long короче, чем остальные пути, поэтому будет выбрана long-реализация метода.

Следующий вызов демонстрирует еще одну возможную ситуацию. Для типа источника uint существуют две возможные реализации, и пути преобразований для них имеют одинаковую длину. В этом случае выбирается та реализация, для которой на диаграмме путь показан сплошной, а не пунктирной стрелкой, потому будет выбрана реализация с параметром long.

Рассмотрим еще ситуацию, приводящую к конфликту. Первый аргумент в соответствии с правилами требует вызова одной реализации, а второй аргумент будет настаивать на вызове другой реализации. Возникнет коллизия, не разрешимая правилами C# и приводящая к ошибке периода компиляции. Коллизию требуется устранить, например, как это сделано в примере. Обратите внимание — обе реализации допустимы, и существуй даже только одна из них, ошибки бы не возникало.

Явные преобразования

Как уже говорилось, явные преобразования могут быть опасными из-за потери точности. Поэтому они выполняются по указанию программиста, — на нем лежит вся ответственность за результаты.

Преобразования строкового типа

Важным классом преобразований являются преобразования в строковый тип и наоборот. Преобразования в строковый тип всегда определены, поскольку, напомню, все типы являются потомками базового класса Object, а, следовательно, обладают методом Tostring(). Для встроенных типов определена подходящая реализация этого метода. В частности, для всех подтипов арифметического типа метод Tostring о возвращает в подходящей форме строку, задающую соответствующее значение арифметического типа. Заметьте, метод Tostring можно вызывать явно, но, если явный вызов не указан, то он будет вызываться неявно, всякий раз, когда по контексту требуется преобразование к строковому типу. Вот соответствующий пример:

///

/// Демонстрация преобразования в строку данных различного типа.

/// 

public void ToStringTest ()

{

Перейти на страницу:

Похожие книги