ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 3167

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

C o n s o l e . R e a d ( ) ;

}

// C h a n g e V a l u e F u n c t i o n - п е р е д а ч а с т р у к т у р ы

по

значению j

p u b l i c s t a t i c v o i 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 ,

 

i n t n e w V a l u e , d o u b l e

dNewValue)

{

t . N =

newValue,-

 

 

T e s t . D = d N e w V a l u e ;

 

 

}

 

 

 

// C h a n g e R e f e r e n c e F u n c t i o n - п е р е д а ч а с т р у к т у р ы по

/ / с с ы л к е

 

 

p u b l i c

s t a t i c v o i d C h a n g e R e f e r e n c e F u n c t i o n ( r e f T e s t t ,

 

i n t n e w V a l u e ,

d o u b l e dNewValue)

{

 

 

 

t . N = n e w V a l u e ;

 

 

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 v o i d 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 i d )

{

 

 

 

C o n s o l e . W r i t e L i n e ( " i d = { o } " , i d . T o S t r i n g ( ) ) ;

 

} }

 

 

 

}

 

 

 

Программа

S t r u c t u r e E x a m p l e сначала определяет

интерфейс

IDisplayableJ

а затем простую структуру 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 .

 

Функция Main () создает объект t e s t вне локальной памяти и использует конструктор для инициализации выделенной ему памяти. Затем M a i n () вызывает функцию Out- p u t F u n c t i o n () для вывода объекта.

Далее функция Main () вызывает функцию 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 .

Следующей вызывается функция ChangeRef 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 ( ) , всегда ис­ пользующий передачу текущего объекта по ссылке, поэтому изменения, сделанные при вызове этого метода, сохраняются при возврате в Main ( ) .

Вывод программы имеет следующий вид:

Начальное з н а ч е н и е

t e s t

 

id = ( 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,000 . 00 ,

2 , 000 . 00)

 

Нажмите

< E n t e r >

д л я

з а в е р ш е н и я п р о г р а м м ы . . .

Структуры и классы имеют одну общую черту: и те и другие порождены из класса Object, указано ли это явно или нет. Этот факт унифицирует различные типы перемен­ ных в одну всеобъемлющую иерархию классов.

Предопределенные типы структур

Схожесть структур и простых типов-значений не только внешняя. В действительно­

сти простые типы-значения являются структурами.

Например,

i n t —

просто

другое

имя структуры I n t 3 2 , d o u b l e — другое имя

структуры

D o u b l e

и так

далее.

В табл. 14.1 приведен полный список типов и соответствующих имен структур.

 

Таблица 14.1. Имена структур для встроенных типов-значений

Имя типа

Имя структуры

 

 

bool

Boolea n

byte

Byte

sbyte

SByte

char

Char

decimal

Decimal

double

Double

float

S i n g l e

int

I n t 3 2

uint

UInt32

Глава 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 - д е м о н с т р а ц и я т о г о , ч т о i n t и I n t 3 2 в

// д е й с т в и т е л ь н о с т и

 

одно

и

то же,

и ч т о

они порождены от

/ / к л а с с а O b j e c t

 

 

 

 

 

 

 

 

 

 

u s i n g S y s t e m ;

 

 

 

 

 

 

 

 

 

 

 

n a m e s p a c e T y p e U n i f i c a t i o n

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

p u b l i c

c l a s s

P r o g r a m

 

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

p u b l i c

s t a t i c v o i d M a i n ( s t r i n g [ ]

a r g s )

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

/ /

С о з д а е м 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 2

i

=

1;

 

 

 

 

 

 

 

 

 

 

 

 

O u t p u t F u n c t i o n ( i ) ;

 

 

 

 

 

 

 

 

II

К о н с т а н т а

2

также

р е а л и з у е т

I F o r m a t t a b l e

 

O u t p u t F u n c t i o n ( 2 ) ;

 

 

 

 

 

 

 

 

//

В д е й с т в и т е л ь н о с т и

вы можете

даже

в ы з в а т ь

м е т о д

/ / к о н с т а н т ы

 

 

 

 

 

 

 

 

 

 

C o n s o l e . W r i t e L i n e ( " Н е п о с р е д с т в е н н ы й

вывод

=

{ о } " ,

 

 

 

 

 

 

 

3 . T o S t r i n g ( ) ) ;

 

 

 

 

 

//

Это

может

быть

п о л е з н ы м ,

н а п р и м е р ,

д л я

выбора

/ / ц е л о г о з н а ч е н и я и з с п и с к а :

 

 

 

 

 

334

Часть V. За базовыми классами


C o n s o l e . W r i t e L i n e ( " \ п В ы б и р а е м и з с п и с к а ц е л ы е " ) ;

o b j e c t [ ] o b j e c t s

=

new o b j e c t [ 5 ] ;

 

o b j e c t s [ 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;

 

 

 

 

o b j e c t s [ 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 ; i n d e x + + )

{

 

 

 

 

 

 

 

 

i f ( o b j e c t s [ i n d e x ]

i s

i n t )

 

 

{

 

 

 

 

 

 

 

i n t n = ( i n t ) o b j e c t s [ i n d e x ] ;

 

 

C o n s o l e . W r i t e L i n e ( " Э л е м е н т { о } — { l } " , i n d e x , n ) ;

 

}

 

 

 

 

 

 

}

 

 

 

 

 

 

 

//

Унификация

т и п о в

п о з в о л я е т в ы в о д и т ь

т и п ы - з н а ч е н и я и

// с с ы л к и , не р а з л и ч а я их

 

C o n s o l e . W r i t e L i n e ( " \ п В ы в о д в с е х о б ъ е к т о в и з с п и с к а " ) ;

i n t n C o u n t = 0;

 

 

 

 

f o r e a c h ( o b j e c t

о

i n o b j e c t s )

 

{

 

 

 

 

 

 

 

 

C o n s o l e . W r i t e L i n e ( " O b j e c t s [ { o } ] - < { l } > " ,

 

n C o u n t + + , o . T o S t r i n g ( ) ) ;

 

}

 

 

 

 

 

 

 

//

Ожидаем

п о д т в е р ж д е н и я

п о л ь з о в а т е л я

 

C o n s o l e . W r i t e L i n e ( " Н а ж м и т е < E n t e r > д л я " +

 

 

 

 

" з а в е р ш е н и я п р о г р а м м ы . . . " ) ;

C o n s o l e . R e a d ( ) ;

 

 

 

 

// 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 v o i d 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 i d )

C o n s o l e . W r i t e L i n e ( " З н а ч е н и е и з O u t p u t F u n c t i o n = { о } " , i d . T o S t r i n g ( ) ) ;

}

// T o S t r i n g - п р о с т а я o v e r r i d e p u b l i c s t r i n g

с т р о к о в а я функция T o S t r i n g ( )

{

r e t u r n " T y p e U n i f i c a t i o n P r o g r a m " ;

Функция Main () начинается с создания объекта i типа i n t . В ней используется конструктор по умолчанию I n t 3 2 О (можно просто написать i n t О ) , который ини­ циализирует переменную i нулевым значением. Далее программа присваивает перемен­ ной i значение 1. Это несколько отличается от формата, используемого при создании структуры.

Глава 14. Интерфейсы и структуры

335


Функция Main () передает переменную 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 . Интерфейсом I F o r m a t t a b l e похож на интерфейс I D i s p l a y a b l e , который определялся в других про граммах. Единственным методом интерфейса I F o r m a t t a b l e является метод ToStrirqj Функция 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 с использование строки, возвращаемой его методом T o S t r i n g ( ) . У переменной I n t 3 2 , которая реал зует этот метод, не возникает никаких проблем. Но самое интересное, что никаких про блем не возникает и при вызове O u t p u t F u n c t i o n ( 2 ) . Поскольку константа 2 имеет тип I n t 3 2 , она также реализует интерфейс I F o r m a t t a b l e . И наконец, фунция

Main ()

вызывает 3. T o S t r i n g () непосредственно. Вывод этой части функции

Main ()

имеет следующий вид:

З н а ч е н и е

из

O u t p u t F u n c t i o n = 1

З н а ч е н и е

из

O u t p u t F u n c t i o n = 2

Н е п о с р е д с т в е н н ы й вывод = 3

Далее функция Main() объявляет массив объектов типа O b j e c t и сохраняет в первом элементе массива s t r i n g , во втором— i n t , в третьем— экземпляр класса Program и т.д. Все это можно сделать, так как S t r i n g , I n t 3 2 и P r o g r a m порождены от Object.Итак массив внутри класса P r o g r a m хранит экземпляр P r o g r a m — правда, это интересно?

Затем программа проходит по всем элементам массива. Функция Main() мо жет выбрать из него все целые числа, запрашивая каждый объект, ЯВЛЯЕТСЯ ли он I n t 3 2 с помощью ключевого слова i s . Вывод этой части программы выглядит следующим образом:

Выбираем и з с п и с к а целые

Элемент

1 — 2

Элемент

3 — 4

Программа завершается демонстрацией использования того факта, что все подклассы Obj e c t — т.е. все классы — реализуют метод T o S t r i n g ( ) . Таким образом, чтобы вы вести все члены массива объектов, вам не надо беспокоиться об их типах. Функция M a i n () просто вновь проходит по массиву, вызывая метод T o S t r i n g () для каждого его элемента. В результате программа выводит на экран следующую информацию:

Вывод

в с е х

о б ъ е к т о в

и з

с п и с к а

 

 

 

 

O b j e c t s

[0]

-

о т о

с т р о к а >

 

 

 

 

O b j e c t s [ 1 ]

-

<2>

 

 

 

 

 

 

 

 

O b j e c t s [ 2 ]

- < T y p e U n i f i c a t i o n P r o g r a m >

 

 

O b j e c t s [ 3 ]

-

<4>

 

 

 

 

 

 

 

 

O b j e c t s [ 4 ]

- < 5 . 5 >

 

 

 

 

 

 

 

Нажмите

< E n t e r >

д л я

з а в е р ш е н и я

п р о г р а м м ы . . .

 

 

Для

класса P r o g r a m

реализован тривиальный

метод T o S t r i n g ( ) , просто чтобы

показать, как это работает.

 

 

 

 

 

 

 

 

Свойство T o S t r i n g ( ) , несомненно, поясняет

магию функции

Console.

 

 

W r i t e ( ) . Честно говоря, даже не смотря исходный текст, можно

поспорить,

 

 

что W r i t e ()

принимает аргументы как принадлежащие типу O b j e c t . Затем

 

 

она

просто вызывает

метод T o S t r i n g ()

для получения выводимой строки,

 

 

которая

подставляется вместо

соответствующего

элемента форматирования

 

 

{п}

в первой строке.

 

 

 

 

 

336

Часть V. За базовыми классами