1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 65
Текст из файла (страница 65)
W r i t e L i n e ( " З н а ч е н и е t e s t после вызова" +" C h a n g e V a l u e F u n c t i o n ( 1 0 0, 2 0 0 . 0 ) " ) ;OutputFunction(test);// Попытка модифицировать о б ъ е к т , п е р е д а в а я е г о в// качестве аргументаChangeReferenceFunction(ref t e s t ,100,200.0);Console.WriteLine("Значение t e s t после вызова" +" ChangeReferenceFunction(100, 200.0)");OutputFunction(test);// Метод может м о д и ф и ц и р о в а т ь о б ъ е к тtest.ChangeMethod(1000,2000.0);C o n s o l e .
W r i t e L i n e ( " З н а ч е н и е t e s t после вызова" +" ChangeMethod(1000, 2 0 0 0 . 0 ) " ) ;OutputFunction(test);/ / Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для " +"завершения п р о г р а м м ы . .
. " ) ;Глава 14. Интерфейсы и структуры331Console.Read();}// C h a n g e V a l u e F u n c t i o n - п е р е д а ч а с т р у к т у р ы по значению jpublic s t a t i c void ChangeValueFunction(Test t,i n t newValue,d o u b l e dNewValue){t . N = newValue,T e s t . D = dNewValue;}// C h a n g e R e f e r e n c e F u n c t i o n - п е р е д а ч а структуры по// ссылкеpublic s t a t i c void ChangeReferenceFunction(ref Test t,i n t newValue,d o u b l e dNewValue){t .
N = newValue;T e s t . D = dNewValue;}/ / O u t p u t F u n c t i o n - в ы в о д и н ф о р м а ц и и о б о б ъ е к т е , который// реализует метод T o S t r i n g ( )p u b l i c s t a t i c void O u t p u t F u n c t i o n ( I D i s p l a y a b l e id){Console.WriteLine("id}}={o}",id.ToString());}Программа S t r u c t u r e E x a m p l e сначала определяет интерфейс I D i s p l a y a b l e Jа затем простую структуру T e s t , которая реализует этот интерфейс. T e s t также определяет два члена — член экземпляра п и статический член d.
Статический инициализатор устанавливает член d равным 20; инициализатор для члена п не разрешен.Структура T e s t определяет конструктор, свойство экземпляра N и статическое свойство D.T e s t также определяет собственный метод C h a n g e M e t h o d () и перекрывает метод!T o S t r i n g ( ) . Предоставлением метода T o S t r i n g ( ) структура T e s t реализует и н терфейс I D i s p l a y a b l e .Функция M a i n () создает объект t e s t вне локальной памяти и использует конструктор для инициализации выделенной ему памяти. Затем M a i n () вызывает функцию Outp u t F u n c t i o n () для вывода объекта.Далее функция M a i n () вызывает функцию C h a n g e V a l u e F u n c t i o n ( ) , передаваяей t e s t с двумя числовыми константами.
Функция C h a n g e V a l u e F u n c t i o n () присваивает эти значения членам п и d структуры T e s t . После возврата из функцииC h a n g e V a l u e F u n c t i o n () вызывается функция O u t p u t F u n c t i o n ( ) , которая позволяет убедиться, что значение d изменилось, а значение п — нет.Вызов C h a n g e V a l u e F u n c t i o n () получает объект t e s t по значению, так что объект t в теле этой функции представляет собой копию исходного объекта t e s t , а не самобъект. Таким образом, присваивание t. N изменяет локальную копию и никак не влияетна объект t e s t e функции M a i n ( ) . Однако все объекты структуры T e s t совместно ис-332Часть V.
За базовыми классам»пользуют статический член d, так что присваивание T e s t . D изменяет d для всех объектов, включая t e s t .Следующей вызывается функция C h a n g e R e f e r e n c e F u n c t i o n ( ) , которая выглядит в точности как и функция C h a n g e V a l u e F u n c t i o n ( ) , за исключением использования в списке аргументов ключевого слова r e f . Это ключевое слово обеспечивает передачу объекта t e s t e функцию по ссылке, так что объект t в функции является ссылкой на исходный объект t e s t , а не вновь созданной копией.Последним вызовом в M a i n () является вызов метода C h a n g e M e t h o d ( ) , всегда использующий передачу текущего объекта по ссылке, поэтому изменения, сделанные привызове этого метода, сохраняются при возврате в M a i n ( ) .Вывод программы имеет следующий вид:Начальное з н а ч е н и е t e s tid = ( 1 0 .
0 0 , 2 0 . 0 0 )Значение t e s t п о с л е в ы з о в а C h a n g e V a l u e F u n c t i o n ( 1 0 0 , 2 0 0 . 0 )id = ( 1 0 . 0 0 , 2 0 0 . 0 0 )Значение t e s t п о с л е в ы з о в а C h a n g e R e f e r e n c e F u n c t i o n ( 1 0 0 , 2 0 0 . 0 )id = ( 1 0 0 . 0 0 , 2 0 0 . 0 0 )Значение t e s t п о с л е в ы з о в а C h a n g e M e t h o d ( 1 0 0 0 , 2 0 0 0 . 0 )id = ( 1 , 0 0 0 . 00 , 2 , 0 0 0 . 0 0 )Нажмите < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы .
. .Структуры и классы имеют одну общую черту: и те и другие порождены из классаObject, указано ли это явно или нет. Этот факт унифицирует различные типы переменных в одну всеобъемлющую иерархию классов.Предопределенные типы структурСхожесть структур и простых типов-значений не только внешняя. В действительности простые типы-значения являются структурами.Например,имя структурыструктурыInt32,d o u b l e — другоеимяi n t — просто другоеDoubleитакдалее.В табл. 14.1 приведен полный список типов и соответствующих имен структур.Таблица 14.1. Имена структур для встроенных типов-значенийИмя типаИмя структурыboolBooleanbyteBytesbyteSBytecharChardecimalDecimaldoubleDoublefloatSingleintInt32uintUInt32Глава 14.
Интерфейсы и структуры333Окончание табл. HIТип s t r i n g является ссылочным, а не типом-значением, поэтому для негонесуществует соответствующей структуры. Вместо этого тип s t r i n g соответствует классу S t r i n g . Тип s t r i n g в С# особенный и обладает рядом свойств,присущих структурам. Более детально он рассматривается в главе 9, "Работаюстроками в С # " .Унификация системы типов с помощью структурТип i n t — другое имя для I n t 3 2 . Поскольку все структуры порождены откласса O b j e c t , i n t также не должен быть исключением. Это приводитк очень интересным результатам, которые демонстрирует приведенная нижепрограмма.// T y p e U n i f i c a t i o n - демонстрация// д е й с т в и т е л ь н о с т и одно и то же,// класса Objectusing System;namespaceтого, что i n t и I n t 3 2 ви ч т о они порождены отTypeUnification{publicclassProgram{publicstaticvoidMain(string[]args){// Создаем i n t и инициализируем е г о нулемi n t i = new i n t ( ) ;/ / Д а , т а к можно д е л а т ь/ / П р и с в а и в а е м е м у з н а ч е н и е 1 и в ы в о д и м п р и помощи// интерфейса I F o r m a t t a b l e , который р е а л и з у е т I n t 3 2i = 1;OutputFunction(i);II К о н с т а н т а 2 такжеOutputFunction(2);реализуетIFormattable// В д е й с т в и т е л ь н о с т и вы можете даже в ы з в а т ь м е т о д// константыC o n s o l e .
W r i t e L i n e ( " Н е п о с р е д с т в е н н ы й вывод = { о } " ,3.ToString());////334Это может быть п о л е з н ы м , н а п р и м е р ,целого значения из списка:длявыбораЧасть V. За базовыми классамиConsole.WriteLine("\пВыбираем из списка целые");object[]o b j e c t s = new o b j e c t [ 5 ] ;objects[0] = "это строка";o b j e c t s [ 1 ] = 2;o b j e c t s [ 2 ] = new P r o g r a m ( ) ;o b j e c t s [ 3 ] = 4;objects[4] = 5.5;f o r ( i n t i n d e x = 0; i n d e x < o b j e c t s . L e n g t h ; index++){if(objects[index]isint){int n = (int)objects[index];Console.WriteLine("Элемент {о}—{l}",index,n);}}// Унификация т и п о в п о з в о л я е т выводить т и п ы - з н а ч е н и я и// ссылки, не р а з л и ч а я ихConsole.WriteLine("\пВывод всех объектов из с п и с к а " ) ;i n t nCount = 0;f o r e a c h ( o b j e c t о in o b j e c t s ){Console.WriteLine("Objects [{o}]nCount++, o .
T o S t r i n g ( ) ) ;- <{l}>",}/ / Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для " +"завершения п р о г р а м м ы . . . " ) ;Console.Read() ;// O u t p u t F u n c t i o n - вывод п р о и з в о л ь н о г о о б ъ е к т а ,// реализующего T o S t r i n g ()public s t a t i c void O u t p u t F u n c t i o n ( I F o r m a t t a b l e id)Console.WriteLine("Значение из OutputFunction =id.ToString());{о}",}// T o S t r i n g - п р о с т а я с т р о к о в а я функцияoverride public string ToString(){return"TypeUnificationProgram";Функция M a i n () начинается с создания объекта i типа i n t .
В ней используетсяконструктор по умолчанию I n t 3 2 О (можно просто написать i n t О ) , который инициализирует переменную i нулевым значением. Далее программа присваивает переменной i значение 1. Это несколько отличается от формата, используемого при созданииструктуры.Глава 14. Интерфейсы и структуры335Функция M a i n () передает переменную i функции O u t p u t F u n c t i o n ( ) , котораяявлена как принимающая объект, реализующий интерфейс I F o r m a t t a b l e .