Как сделать переменную (не член класса) "только для чтения" в C # - PullRequest
4 голосов
/ 08 января 2011

Я новичок в мире C # и не могу найти метод для объявления переменной только для чтения в C # (что-то вроде объявления переменной "const" в c ++).Есть один?

Я приведу пример:

...
int f() { return x; } // x is not const member
...
void g() {
    int readOnlyVar = f(); // is there a method to declare readOnlyVar as read only or const

    // Some code in which I want to restrict access to readOnlyVar to read only 
}

Ответы [ 5 ]

11 голосов
/ 08 января 2011

Аналога не существует.

Ключевое слово readonly позволяет изменять значение переменной, но только в конструкторе.

Ключевое слово const означает значениене может изменяться и должен быть постоянной времени компиляции и может быть только одним из следующих типов: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum-типа или ссылочный тип.(C # 4.0 spec §10.4).

А в c # readonly применяется только к полям и не может применяться к локальным переменным.

4 голосов
/ 08 января 2011

Нет, для вашего примера кода не существует решения.

const в C # - для констант времени компиляции, и поскольку ваша переменная получает свое значение от функции, она не известна во время компиляции.

Ключевое слово readonly делает то, что вы ищете, но это только для переменных-членов в классах (и позволяет устанавливать переменные только в конструкторе класса).

Но, с другой стороны, зачем вам это нужно? Если ваша функция очень длинная, она должна быть преобразована в меньшие функции. Если это не очень долго, то зачем вам применять такое правило? Боюсь, просто не назначайте readOnlyVar, наверное, мое лучшее предложение для вас.

2 голосов
/ 08 января 2011

Существует два способа установить переменную только для чтения.

public class ClassA
{
  private const int I = 5;
  private readonly int J = 5;
}

Ключевое слово const устанавливает значение во время компиляции. Ключевое слово readonly будет устанавливать значение при построении. Итак, если вам нужны разные значения для каждого экземпляра, используйте readonly. В противном случае используйте const.

2 голосов
/ 08 января 2011

в c # мы имеем ключевое слово const или readonly для объявления константы.

сопзЬ

Постоянный член определяется во время компиляции и не может быть изменен во время выполнения. Константы объявляются как поле с использованием ключевого слова const и должны быть инициализированы так, как они объявлены. Например;

public class MyClass
{
  public const double PI = 3.14159;
}

PI нельзя изменить в приложении где-либо еще в коде, так как это приведет к ошибке компиляции.

* 1013 только для чтения *

Член только для чтения похож на константу в том смысле, что он представляет собой неизменное значение. Разница в том, что элемент readonly может быть инициализирован во время выполнения в конструкторе, а также может быть инициализирован так, как он объявлен. Например:

public class MyClass
{
  public readonly double PI = 3.14159;
}   

или

public class MyClass
{
  public readonly double PI;

  public MyClass()
  {
    PI = 3.14159;
  }
}

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

public static readonly uint l1 = (uint)DateTime.Now.Ticks;

Примечания

члены только для чтения не являются неявно статическими, и поэтому ключевое слово static может быть применено к полю только для чтения, если требуется.

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

кредит идет сюда: http://www.dotnetspider.com/forum/69474-what-final-c-i-need-detailed-nfo.aspx

0 голосов
/ 21 октября 2016

Это не языковая функция, но вы не единственный человек, заинтересованный в такой функции . У вас есть несколько вариантов, хотя. Вы можете заменить реализацию вашего метода классом, который имеет readonly переменные-члены. Это большая боль, и она действительно взрывает размер вашего кода. (Когда вы пишете лямбда-выражения или используете async методы, C # делает нечто подобное, чтобы поднять локальные переменные в поля классов и превращает ваш лямбда-или асинхронный метод в методы автоматически генерируемого класса. set readonly.)

class Scope
{
    int x;

    int f() => x; // x is not const member

    void g()
    {
        new gImpl(f()).Run();
    }

    class gImpl
    {
        readonly int readOnlyVar;
        public gImpl(
            int readOnlyVar)
        {
            this.readOnlyVar = readOnlyVar;
        }
        public void Run()
        {
            // Some code in which I want to restrict access to readOnlyVar to read only 

            // error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
            readOnlyVar = 3;
        }
    }
}

Другая альтернатива, которая требует меньше кода, но все еще неуклюжа, - это использовать функцию foreach. Ключевое слово foreach не позволяет назначать переменную итерации. Таким образом, вы можете сделать что-то вроде этого:

class Scope
{
    int x;

    int f() => x;

    void g()
    {
        foreach (var readOnlyVar in new[] { f(), })
        {
            // Some code in which I want to restrict access to readOnlyVar to read only 

            // error CS1656: Cannot assign to 'readOnlyVar' because it is a 'foreach iteration variable'
            readOnlyVar = 3;
        }
    }
}

Метод foreach упрощает использование анонимных типов, но вы можете использовать обобщения в сочетании с выводом типов для использования анонимных типов с методом класса.

...