Поля, объявленные с ключевым словом static, называются статическими полями, в то время как поля без static именуют полями экземпляра или данными экземпляра. Поле экземпляра можно считать принадлежащим объекту, а статическое поле – принадлежащим классу.
Поле, объявленное как static существует пока программа выполняется, начиная с того момента, как был загружен соответствующий модуль или сборка, содержащая определение класса. Это происходит когда код пытается использовать что-либо из сборки, поэтому можно гарантировать, что статическая переменная всегда будет существовать. Это не зависит от того, были ли объявлены какие-нибудь переменные данного класса. В некотором смысле статические поля выполняют те же функции, что и глобальные переменные.
Ключевое слово static не зависит от модификатора доступа (на практике вроде бы иначе!).
Следует всегда вызывать статические методы, используя имя класса, а методы экземпляра, указывая имя экземпляра класса. Методы экземпляра, так же как и статические методы, хранятся в памяти только в оном месте и связаны с классом в целом.
Как метод получает доступ к правильной копии каждого пароля? Методы экземпляра получают дополнительный неявный параметр, который является ссылкой на место в памяти, где хранятся данные соответствующего экземпляра класса.
Нельзя получить доступ к полям экземпляра класса из метода, объявленного как static!
Классы являются типами по ссылке, каждая переменная содержит только ссылку на то место в памяти, где храниться экземпляр класса, а не сами данные, предоставляющие собой экземпляр кл.
Свойства – это метод, или пара методов, которые для пользователя выглядят как поля. Свойства предусмотрены та тот случай, когда необходимо сделать вызов метода похожим на поле.
// свойство public static byte MinPasswordLength { get { return minPasswordLength; } // аксесор доступа get set { minPasswordLength = value;} // аксесор доступа set }
Аксесор доступа Get всегда возвращает тот же тип данных, какое имеет объявленное свойство (byte). Аксесор доступа Set имеет невидимый параметр value – значение которое присваивается свойству. Если к свойству обращаться так, что значение должно быть возвращено (обычно в правой части), то неявно вызывается аксесор Get, который возвращает соответствующее значение.
byte b = Authenticator.MinPasswordLength;
Если свойству должно быть присвоено значение, то вызывается аксесор set. Если реализовано свойство тогда можно также: Authenticator.MinPasswordLength += 7;
Наследование
Все классы в C# являются производными от Syatem.Object.
Существует возможность указывать на производные классы с помощью ссылки на базовый. Как компилятор определяет какой метод вызывать (для базового класса – собственно тип нашей ссылки, или для реального – идущего после слова new)?
Customer Alex = new Nevermore60Customer(); Alex.RecordCall(TypeOfCall.CallToMobile, 5);
- Если метод является не виртуальным, компилятор использует тот тип, который ссылка имела при объявлении. В данном случае ссылка имеет тип Customer, поэтому будет вызван метод Customer.RecordCall(), не зависимо от того, на что действительно ссылается Alex;
- Если метод является виртуальным, компилятор сгенерирует код, который будет во время исполнения проверять, куда на самом деле указывает ссылка Alex. Затем оно определяет экземпляром какого класса является данный экземпляр и вызывает соответствующий перекрывающий метод.
При вызове виртуальной функции необходимо осуществлять проверки во время выполнения (для не виртуальной функции эта информация доступна во время компиляции). Это снижает производительность. Способность вызывать метод по ссылке и заставлять его делать то, что свойственно данному классу, известна как полиморфизм.
Память
Сборщик мусора занимается:
- Убирает все объекты из кучи, ссылки на которые не существуют;
- Освободив все объекты, он уплотняет память (дефрагментирует) перемещая их ближе к куче для формирования одного непрерывного блока;
- После перемещения обновляет все ссылки на перемещенные объекты, чтобы они содержали новые, корректные адреса.