Рассмотрим частный случай присваивания x = e; когда x имеет тип object. В этом случае гарантируется полная согласованность по присваиванию - выражение e может иметь любой тип. В результате присваивания значением переменной x становится ссылка на объект, заданный выражением e. Заметьте, текущим типом x становится тип объекта, заданного выражением e. Уже здесь проявляется одно из важных различий между классом и типом. Переменная, лучше сказать сущность x, согласно объявлению принадлежит классу Object, но ее тип - тип того объекта, с которым она связана в текущий момент, - может динамически изменяться.
Примеры преобразований
Перейдем к примерам. Класс Testing, содержащий примеры, представляет собой набор данных разного типа, над которыми выполняются операции, иллюстрирующие преобразования типов. Вот описание класса Testing:
using System;
namespace Types
{
///
/// Класс Testing включает данные разных типов. Каждый его
/// открытый метод описывает некоторый пример,
/// демонстрирующий работу с типами.
/// Открытые методы могут вызывать закрытые методы класса.
///
public class Testing
{
///
/// набор скалярных данных разного типа.
///
byte b = 255;
int x = 11;
uint ux = 1111;
float y = 5.5f;
double dy = 5.55;
string s = "Hello!";
string s1 = "25";
object obj = new Object();
// Далее идут методы класса, приводимые по ходу
// описания примеров
}
}
В набор данных класса входят скалярные данные арифметического типа, относящиеся к значимым типам, переменные строкового типа и типа object, принадлежащие ссылочным типам. Рассмотрим закрытый (private) метод этого класса - процедуру WhoIsWho с формальным аргументом класса Object. Процедура выводит на консоль переданное ей имя аргумента, его тип и значение. Вот ее текст:
///
/// Метод выводит на консоль информацию о типе и
/// значении фактического аргумента. Формальный
/// аргумент имеет тип object. Фактический аргумент
/// может иметь любой тип, поскольку всегда
/// допустимо неявное преобразование в тип object.
///
///
- Имя второго аргумента
///
- Допустим аргумент любого типа
void WhoIsWho(string name, object any)
{
Console.WriteLine("type {0} is {1} , value is {2}",
name, any.GetType(), any.ToString());
}
Вот открытый (public) метод класса Testing, в котором многократно вызывается метод WhoIsWho с аргументами разного типа:
///
/// получаем информацию о типе и значении
/// переданного аргумента - переменной или выражения
///
public void WhoTest()
{
WhoIsWho("x",x);
WhoIsWho("ux",ux);
WhoIsWho("y",y);
WhoIsWho("dy",dy);
WhoIsWho("s",s);
WhoIsWho("11 + 5.55 + 5.5f",11 + 5.55 + 5.5f);
obj = 11 + 5.55 + 5.5f;
WhoIsWho("obj",obj);
}
Заметьте, сущность any - формальный аргумент класса Object при каждом вызове - динамически изменяет тип, связываясь с объектом, заданным фактическим аргументом. Поэтому тип аргумента, выдаваемый на консоль, - это тип фактического аргумента. Заметьте также, что наследуемый от класса Object метод GetType возвращает тип FCL, то есть тот тип, на который отражается тип языка и с которым реально идет работа при выполнении модуля. В большинстве вызовов фактическим аргументом является переменная - соответствующее свойство класса Testing, но в одном случае передается обычное арифметическое выражение, автоматически преобразуемое в объект. Аналогичная ситуация имеет место и при выполнении присваивания в рассматриваемой процедуре.
На рис. 3.1 показаны результаты вывода на консоль, полученные при вызове метода WhoTest в приведенной выше процедуре Main класса Class1.
Do'stlaringiz bilan baham: |