Страница 113 из 502
• Аналогичные ограничения накладываются на данные типа static. Для метода типа static непосредственно доступными оказываются только другие данные типа static, определенные в его классе. Он, в частности, не может оперировать переменной экземпляра своего класса, поскольку у него отсутствуют объекты, которыми он мог бы оперировать.
Ниже приведен пример класса, в котором недопустим метод ValDivDenom() типа static.
<b>class StaticError {</b>
<b> public int Denom =3; // обычная переменная экземпляра </b>
<b> public static int Val = 1024; // статическая переменная</b>
<b> /* Ошибка! Непосредственный доступ к нестатической переменной из статического метода недопустим. */ </b>
<b> static int ValDivDenom() {</b>
<b> return Val/Denom; // не подлежит компиляции!</b>
<b> }</b>
<b>}</b>
В данном примере кода Denom является обычной переменной, которая недоступна из метода типа static. Но в то же время в этом методе можно воспользоваться переменной Val, поскольку она объявлена как static.
Аналогичная ошибка возникает при попытке вызвать нестатический метод из статического метода того же самого класса, как в приведенном ниже примере.
<b>using System;</b>
<b>class AnotherStaticError {</b>
<b>// Нестатический метод. </b>
<b> void NonStaticMeth() {</b>
<b> Console.WriteLine("В методе NonStaticMeth().");</b>
<b> }</b>
<b> /* Ошибка! Непосредственный вызов нестатического метода из статического метода недопустим. */ </b>
<b> static void staticMeth() {</b>
<b> NonStaticMeth(); // не подлежит компиляции!</b>
<b> }</b>
<b>}</b>
В данном случае попытка вызвать нестатический метод (т.е. метод экземпляра) из статического метода приводит к ошибке во время компиляции.
Следует особо подчеркнуть, что из метода типа static нельзя вызывать методы экземпляра и получать доступ к переменным экземпляра его класса, как это обычно делается посредством объектов данного класса. И объясняется это тем, что без указания конкретного объекта переменная или метод экземпляра оказываются недоступными. Например, приведенный ниже фрагмент кода считается совершенно верным.
<b>class MyClass {</b>
<b>// Нестатический метод. </b>
<b> void NonStaticMeth() {</b>
<b> Console.WriteLine("В методе NonStaticMeth().");</b>
<b> }</b>
<b> /* Нестатический метод может быть вызван из статического метода по ссылке на объект. */ </b>
<b> public static void staticMeth(MyClass ob) { </b>
<b> ob.NonStaticMeth(); // все верно!</b>
<b> }</b>
<b>}</b>
В данном примере метод NonStaticMeth() вызывается из метода staticMeth() по ссылке на объект ob типа MyClass.
Поля типа static не зависят от конкретного объекта, и поэтому они удобны для хранения информации, применимой ко всему классу. Ниже приведен пример программы, демонстрирующей подобную ситуацию. В этой программе поле типа static служит для хранения количества существующих объектов.
<b>// Использовать поле типа static для подсчета </b>
<b>// экземпляров существующих объектов.</b>
<b>using System;</b>
<b>class CountInst {</b>
<b> static int count = 0;</b>
<b> // Инкрементировать подсчет, когда создается объект.</b>
<b> public CountInst() {</b>
<b> count++;</b>
<b> }</b>
<b> // Декрементировать подсчет, когда уничтожается объект.</b>
<b> ~CountInst() { count--;</b>
<b> }</b>
<b> public static int GetCount() { </b>
<b> return count;</b>
<b> }</b>
<b>}</b>
<b>class CountDemo {</b>
<b> static void Main() {</b>
<b> CountInst ob;</b>
<b> for(int i=0; i < 10; i++) {</b>
<b> ob = new CountInst();</b>
<b> Console.WriteLine("Текущий подсчет: " + CountInst.GetCount());</b>
<b> }</b>
<b> }</b>
<b>}</b>
Выполнение этой программы приводит к следующему результату.