Добавить в цитаты Настройки чтения

Страница 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(&quot;В методе NonStaticMeth().&quot;);</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(&quot;В методе NonStaticMeth().&quot;);</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 &lt; 10; i++) {</b>

<b>      ob = new CountInst();</b>

<b>      Console.WriteLine(&quot;Текущий подсчет: &quot; + CountInst.GetCount());</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

Выполнение этой программы приводит к следующему результату.