Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Глобальная переменная си шарп

Область видимости переменных, константы

C# — Руководство по C# — Область видимости переменных, константы

Область видимости переменных

Область видимости, или контекст переменной — это часть кода, в пределах которого доступна данная переменная. В общем случае такая область определяется описанными ниже правилами:

Поле, также известное как переменная-член класса, находится в области видимости до тех пор, пока в этой области находится содержащий поле класс.

Локальная переменная находится в области видимости до тех пор, пока закрывающая фигурная скобка не укажет конец блока операторов или метода, в котором она объявлена.

Локальная переменная, объявленная в операторах цикла for, while или подобных им, видима в пределах тела цикла.

Конфликты областей видимости локальных переменных

Использование в больших программах одних и тех же имен переменных в разных частях программы является обычной практикой. Это нормально до тех пор, пока области видимости этих переменных не перекрываются и находятся в совершенно разных частях программы, таким образом исключая любую неоднозначность. Однако следует иметь в виду, что локальные переменные с одним и тем же именем не могут быть объявлены дважды в одном и том же контексте, поэтому вы не сможете поступить так, как показано ниже:

Рассмотрим следующий пример кода:

Важно отметить, что переменная i объявляется в этом коде два раза в пределах одного и того же метода. Это можно делать, поскольку переменные i объявляются в двух отдельных циклах, поэтому каждая из них локальна в пределах собственного цикла.

Вот другой пример:

Если вы попытаетесь скомпилировать это, то получите следующее сообщение об ошибке:

ScopeTest.cs (12,15) : error CS0136: A local variable named ‘3’ cannot be declared in this scope because it would give a different meaning to ‘j’, which is already used in a ‘parent or current’ scope to denote something else

Дело в том, что переменная j, которая определена перед началом цикла for, внутри цикла все еще находится в области видимости и не может из нее выйти до завершения метода Main(). Хотя вторая переменная j (недопустимая) объявлена в контексте цикла, этот контекст вложен в контекст метода Main(). Компилятор не может различить эти две переменных, поэтому не допустит объявления второй из них.

Конфликты областей видимости полей и локальных переменных

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

Этот код компилируется, несмотря на то, что здесь в контексте метода Main() присутствуют две переменных с именем j: переменная j, определенная на уровне класса и существующая до тех пор, пока не будет уничтожен класс (когда завершится метод Main(), а вместе с ним и программа), и переменная j, определенная внутри Main(). В данном случае новая переменная с именем j, объявленная в методе Main(), скрывает переменную уровня класса с тем же именем. Поэтому когда вы запустите этот код, на дисплее будет отображено число 30.

Константы

Как следует из названия, константа — это переменная, значение которой не меняется за время ее существования. Предваряя переменную ключевым словом const при ее объявлении и инициализации, вы объявляете ее как константу:

Ниже перечислены основные характеристики констант:

Они должны инициализироваться при объявлении, и однажды присвоенные им значения никогда не могут быть изменены.

Значение константы должно быть вычислено во время компиляции. Таким образом, инициализировать константу значением, взятым из другой переменной, нельзя. Если все-таки нужно это сделать, используйте поля только для чтения.

Константы всегда неявно статические. Однако вы не должны (и фактически не можете) включать модификатор static в объявление константы.

Использование констант в программах обеспечивает, по крайней мере, три преимущества:

Константы облегчают чтение программ, заменяя «магические» числа и строки читаемыми именами, назначение которых легко понять.

Константы облегчают модификацию программ. Например, предположим, что в программе C# имеется константа SalesTax (налог с продаж), которой присвоено значение 6 процентов. Если налог с продаж когда-нибудь изменится, вы можете модифицировать все вычисления налога, просто присвоив новое значение этой константе, и не понадобится просматривать код в поисках значений и изменять каждое из них, надеясь, что оно нигде не будет пропущено.

Константы позволяют избежать ошибок в программах. Если попытаться присвоить новое значение константе где-то в другом месте программы, а не там, где она объявлена, компилятор выдаст сообщение об ошибке.

Область видимости переменных

Переменные могут быть полями класса, объявляться в функциях или даже внутри циклов (например: for (int i=0; i

Область видимости, или контекст переменной — это часть кода, в пределах которого доступна данная переменная. В общем случае такая область определяется описанными ниже правилами:
1. Поле, также известное как переменная-член класса, находится в области видимости до тех пор, пока в этой области находится содержащий поле класс.
2. Локальная переменная находится в области видимости до тех пор, пока закрывающая фигурная скобка не укажет конец блока операторов или метода, в котором она объявлена.
3. Локальная переменная, объявленная в операторах цикла for, while или подобных им, видима в пределах тела цикла.

Читать еще:  Диспетчер устройств ошибка 10

Конфликты областей видимости локальных переменных.
Использование в больших программах одних и тех же имен переменных в разных частях программы является обычной практикой. Это нормально до тех пор, пока области видимости этих переменных не перекрываются и находятся в совершенно разных частях программы, таким образом, исключая любую неоднозначность.

Однако следует иметь в виду, что локальные переменные с одним и тем же именем не могут быть объявлены дважды в одном и том же контексте, поэтому вы не сможете поступить так, как показано ниже:
int х = 20;
// какой-то код
int х = 30;

Рассмотрим следующий пример кода с локальной переменной k (оператор цикла for изучается дальше):

Важно отметить, что переменная k объявляется в этом коде два раза в пределах одного и того же метода Main(). Это можно делать, поскольку переменные k объявляются в двух отдельных циклах, поэтому каждая из них локальна в пределах собственного цикла.
Рассмотрим другой пример:

Если вы попытаетесь скомпилировать это, то получите следующее сообщение об ошибке:
Ошибка: Невозможно объявить локальную переменную с именем «k» в этой области видимости, т.к. она придаст другое значение «k», которая уже используется в области видимости «родительский или текущий» для обозначения чего-то другого.
Дело в том, что переменная k, которая определена перед началом цикла for, внутри цикла все еще находится в области видимости и не может из нее выйти до завершения метода Main().
Хотя вторая переменная k (недопустимая) объявлена в контексте цикла, этот контекст вложен в контекст метода Main(). Компилятор не может различить эти две переменных, поэтому не допустит объявления второй из них.

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

Рассмотрим третий пример:

Этот код компилируется, несмотря на то, что здесь в контексте метода Main() присутствуют две переменных с именем k: переменная k, определенная на уровне класса и существующая до тех пор, пока не будет уничтожен класс (когда завершится метод Main(), а вместе с ним и программа), и переменная k, определенная внутри Main().

В данном случае новая переменная с именем k, объявленная в методе Main(), игнорирует переменную уровня класса с тем же именем. Поэтому когда вы запустите этот код, на дисплее будет отображено число 30.
В языке C# локальные переменные широко используются именно из-за аппарата разграничения области видимости. Не экономьте без необходимости на локальных переменных, если они не занимают большой объем памяти.

Следующее интуитивно понятие языка программирования — Литералы.

Глобальная переменная си шарп

Лучший отвечающий

Вопрос

Я понимаю что понятие глобальной переменной в C# нет, но суть в том что при старте программы она загружает настройки в некий объект, далее они повсеместно используются. На данный момент я объявил объект в главной форме, в дочернем окне (SDI интерфейс), AppSettings уже «Не существует в текущем контексте», а передавать повсюду и повсеместно ссылку на объект хранящий переменные как-то излишне.

Могу ли я объявить объект в где-то в program.cs чтоб он был виден везде?

  • Перемещено Siddharth Chavan 1 октября 2010 г. 21:36 MSDN Forums Consolidation (От:Visual C#)

Ответы

Создавайте экземляр этого класса как статический член любого класса оболочки — поместите этот класс в области видимости всех форм и через статическое свойство спокойно получайте доступ к единственному экземпляру вашего объекта AppSett

и т.д. Один экземпляр объекта-свойств на все формы во всем приложении, что собственно в начале и было написано.

  • Помечено в качестве ответа PhantomSL 24 марта 2010 г. 16:45

Ну в форму его не надо помещать, зачем — это же глобальные настройки для всего приложения. В принципе его не надо вобще делать вложенным класом, поместите его в то же пространство имен, где ваш класс Program объявлен, хотя бы вот так:

Ну это все дело удобства, а теоретически его куда угодно можно поместить. В частности VS добавляет автоматически пространство имен Properties с кдассом глобальных настроек Settings — его и туда можно поместить.

  • Помечено в качестве ответа PhantomSL 24 марта 2010 г. 13:37
  • Снята пометка об ответе PhantomSL 24 марта 2010 г. 14:09
  • Помечено в качестве ответа PhantomSL 24 марта 2010 г. 16:45

Все ответы

Видимо я или не понял сути или не верно задал вопрос, так что вношу дополнения:

1. Я не нашел более менее вразумительно способа для сохранения настроек в .Net Compact в итоге был написан такой класс:

И он задействуется: в главной форме: Так что .Net Compact и условия XML сериализации несколько сдерживают применение статических классов и т.д. Вот я и спрашивал ГДЕ именно объявить Settings Appset чтоб видеть в дочерних формах?

Вам необходимо создать public класс-сингльтон, в который при старте нужно записывать данные и потом использовать где-либо в приложении.

Читать еще:  Excessive deferral ошибки

Создавайте экземляр этого класса как статический член любого класса оболочки — поместите этот класс в области видимости всех форм и через статическое свойство спокойно получайте доступ к единственному экземпляру вашего объекта AppSett

и т.д. Один экземпляр объекта-свойств на все формы во всем приложении, что собственно в начале и было написано.

  • Помечено в качестве ответа PhantomSL 24 марта 2010 г. 16:45

Вам необходимо создать public класс-сингльтон, в который при старте нужно записывать данные и потом использовать где-либо в приложении.

>> Посмотрите выше и убедитесь, что у меня и есть непотокобезопасный синглтон.

Убедился. Но, думаю, нужно было описать, почему именно такой код нужно использовать.

>> Посмотрите выше и убедитесь, что у меня и есть непотокобезопасный синглтон.

Убедился. Но, думаю, нужно было описать, почему именно такой код нужно использовать.

«Создавайте экземляр этого класса как статический член любого класса оболочки — поместите этот класс в области видимости всех форм и через статическое свойство спокойно получайте доступ к единственному экземпляру вашего объекта AppSett»

Я новичек в C# и меня более всего интересует «поместите этот класс в области видимости всех форм»

Глобальные переменные в C#

Сегодня задали интересный вопрос — как и где хранить глобальные переменные. Человек привык создавать в Delphi отдельный модуль, в котором хранил глобальные переменные и методы. Это большая проблема Delphi, что он умеет создавать глобальные переменные. По правилам OOP не должно быть такой возможности, и в C# такой возможности нет!

Но как же тогда поступить, если хочется создать что-то глобальное? Сначала нужно подумать 10 раз, а действительно ли нужна эта глобальность. Забудьте Delphi как страшный сон и вообще забудьте, что может быть такая возможность, как глобальная переменная или метод. Просто подумайте и ответьте себе на следующие вопросы:

1. Действительно ли нужно, чтобы к переменной мог быть доступ откуда угодно? Если нет, то создайте свойство у какого-нибудь самого подходящего класса.

2. Может переменная по смыслу относится к какому-то классу? Если да, то опять же создайте свойство у какого-нибудь самого подходящего класса.

3. Может у вас код логики в классах с визуальным интерфейсом? Если да, то лучше удалить код, и начать писать заново, только проектировать код, а не лепить.

Если ты сейчас думаешь «да задолбал ты, просто скажи, как сделать глобальную переменную или метод», то в таком случае просто говорю:

В таких случаях в C# и других реально объектных языках используют статичные переменные и методы. Просто создайте файл, в который будете кидать весь свой глобальный мусор:

Теперь в любом месте программы вы можете обратиться к переменным и методам так: GlobalTrash.MyGlobalTrash.MiGlobalVariable = 10;. Но еще раз хочу посоветовать создавать глобальные переменные только в крайнем случае.

В принципе, можно не создавать отдельный класс и namespace, а использовать класс Program, который итак уже есть в программе в файле Program.cs.

Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым

А еще поделитесь с друзьями

Комментарии

Spider_NET

Этим мне и нравиться C#. После перехода с Delphi мне было чертовски непривычно, но потом я прочувствовал эту фичу. И код легче поддерживать (я про static) и все как-то на виду, в отличии от Delphi.

Хотя это относится к старым версия дельфина. В последних версиях, в Delphi появились так называемые классовые методы/переменные — аля статичные.

Все таки хорошо, что Delphi продолжает развиваться.

psycho-coder

Я как-то писал клиент для MySQL на C++.NET (изврат конечно), но там нужно было где-то хранить настройки (пароль, имя пользователя, порт, имя базы и т.д.). Пришлось делать через глобальные переменные, т.к. окон было много, приписать к какому то классу было нельзя, а может и можно (на ум ничего не пришло).
Как быть в таких случаях?

Еще намучался с передачей данных между формами, где то можно было напрямую с одной формы на другую, а где то, только через глобы(

Михаил Фленов

Зачем настройки соединения нужны окнам? Они нужны там только в одном случае — у тебя код доступа к базе находиться в классах с окнами. Это очень плохо. Нужно отделить это дело.

Сергей

psycho-coder

Ммм. Нужно выкинуть код доступа к базе в отдельный класс? Тогда значит, нужно передавать из класса данные, которые будут получены из базы, в класс окна и заполнять все поля этими данными?

Михаил Фленов

Delphi — очень хороший язык. Но любому программисту, перешедшему с Delphi на C# нужно забыть практически все, что он делал на Delphi.

Точно так же я скажу любому программисту, который переходит с C# или Java на Delphi — «забудьте C# и Java». Иначе не получиться написать успешный проект.

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

Читать еще:  Ошибка при запуске приложения 0хс0000005

Михаил Фленов

Жди отдельную заметку

Михаил Фленов

Решил все же не писать заметку.

Подход Delphi: компоненты доступа к данным располагаются в отдельном модуле DataModule. Этот модуль создается при запуске приложения и любая форма обращается к модулю и может выполнять запросы у себя в классе и обрабатывать данные.
В принципе, ты можешь то же самое реализовать на C#. Создай отдельный класс, который будет создаваться при запуске приложения. Это будет у тебя как бы DataModule. Можешь даже называть его так же. Ссылка на класс будет статична (глобальна). В этом классе будет компонент для создания соединения с базой данных и объекта таблиц и запросов. Ты можешь в любом окне обратиться через статичную переменную к этому классу и получить объект любой таблицы для работы с ним. Не нужно хранить глобально все параметры, достаточно одной переменной, указывающий на объект модуля данных.
Но я уже давно говорю, что надо идти дальше и полностью отделять код от логики. Форма должна получать от DataModule не объект, через который можно получить данные, а НЕПОСРЕДСТВЕННО ДАННЫЕ. В формах должны быть вызовы в стиле:

Результатом может быть набор данных, и можно даже в виде массивов, а не в виде Table.
Опять же, в Delphi можно так же сделать, но никто не делает, потому что сама VCL написана в стиле 70-хх годов и примеры с Delphi поставляются в стиле 70-х годов.

psycho-coder

2Михаил
Спасибо. Нужно будет подумать над этим хорошенько). А прогу придется переписывать с нуля, т.к. исправлять то что там есть нет смысла.

[offtop]я только что понял, что не могу нормально высказать мысль((([/offtop]

Дмитрий

[QUOTE]
Delphi — очень хороший язык. Но любому программисту, перешедшему с Delphi на C# нужно забыть практически все, что он делал на Delphi.

Точно так же я скажу любому программисту, который переходит с C# или Java на Delphi — «забудьте C# и Java». Иначе не получиться написать успешный проект.

Писать действительно можно одинаково, но не всегда это нужно. Просто у этих языков и библиотек подход разный. Я считаю, что писать нужно с использованием языка и его преимуществ. А не пытаться реализовать в языке преимущества других.
[/QUOTE]
Здравствуйте Михаил!
Для начала хотелось бы выразить Вам признательность и уважение за ваши книги. Буквально недавно я учился программировать по второму изданию Библии Delphi. И это помогло мне совершить «быстрый старт». Это была первая моя бумажная книга по программированию.
Но, я все-таки хочу выразить несогласие с тезисами такими как «забудьте как вы делали в Дельфи». Просто потому что как раз в подходах особой разницы между дельфи и сишарп нету. Есть разница в концепции, но это нас прикладных программистов сильно не волнует.
Вот например, я в своих проектах вообще не использую подпрограммы и переменные вне классов, и даже перемещаю из модуля с классом формы глобальный экземпляр в dpr-файл.
Дальше, с событиями, дженериками, анонимными методами и атрибутами я познакомился в дельфи.
Читая MSDN по C# я практически не встречаю революционно нового — основное уже знакомо по дельфи, не считая специфичных штучек дотнета.
Про различия в архитекуре стандартных библиотек — да, ядро RTL сделано в процедурном стиле. Основная причина этого — быстродействие.
Но главное достоинство дельфи VCL является как раз таки олицетворением ООП подхода, и стала прообразом Windows.Forms.
Я это все к тому что не стоит вешать ярлыки на дельфистов якобы они все используют глобальные переменные. Тут предоставляется свобода и программист сам решает, вот я для себя и выбрал объектно-ориентированный подход.
Почему я изучаю C#? Ответ прост: более богатая стандартная библиотека, WPF, ASP.NET, и легче найти работу.
С уважением, Дмитрий.

Михаил Фленов

«забудьте как вы делали в Дельфи» потому что в Дельфи можно использовать глобальные переменные, а в C# их просто нету (может я что-то упускаю).

У C# и Delphi все же много разного. VCL очень похожа на Delphi, но они только похожи. Лично для меня эти языки больше разные, чем похожие.

Дмитрий

Они изначально должны были быть похожи, хотя бы потому, что их проектировал один человек.
Сначала сишарп много позаимствоал из дельфи, а теперь дельфи заимствует у сишарпа.
С С++ намного меньше схожести, синтаксис не считается, т.к. это не принципиально.
Кто-то не помню точно кто сказал что сишарп это 75% джавы и 25% дельфи. Теперь про дельфи можно сказать что там 50% сишарпа.
Не знаю, может Вы просто совсем не следите за последними версиями дельфи?

Дмитрий

А как быть например со строкой доступа к БД, которая формируется в окне авторизации и должна быть доступна всему приложению? Где ее хранить?

Михаил Фленов

Строка подключения не должна быть доступна всему приложению. Она должна быть доступна только одному — двум классам, в которых ты работаешь с данными и где у тебя будут находиться объекты SqlConnection.

Владимир

Проблема — в одном из классов библиотечной сборки нужно установить событие, которое бы виделось в главной сборке, ну и во всех остальных заодно.

Ссылка на основную публикацию
Adblock
detector