Вопрос по c# – Почему C # не поддерживает const на уровне класса / метода?

25

Некоторое время я задавался вопросом, почему C # не поддерживаетconst на уровне класса или метода. Я знаю, что Джон Скит давно хотел поддержки неизменности, и я согласен, что использование синтаксиса C ++ функции const может помочь в этом. Если добавить ключевое слово const на уровне класса, мы получим полную поддержку.

Теперь мой вопрос: в чем причина того, что команда C # не разработала такую поддержку?

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

Вообразите это:

<code>const class NumberContainer
{
    public int Number { get; }
}
</code>

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

Другой пример - const на уровне метода:

<code>public int AddNumbers(NumberContainer n1, NumberContainer n2) const
{
   return n1.Number + n2.Number;
}
</code>

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

Я не совсем уверен, что лямбды и делегаты сделают все слишком трудным (или невозможным) для достижения, но я уверен, что кто-то с большим опытом в области языка и дизайна компилятора мог бы сказать мне.

Как отметил Стив Б. в комментариях, существованиеreadonly делает вещи немного сложнее, как const иreadonly близки к тому же во времяruntime, ноreadonly значения не могут быть определены во время компиляции. Я думаю, мы могли бы иметьconst а такжеreadonly уровень, но это может быть слишком запутанным?

Итак, в чем причина не реализовывать это? Проблемы юзабилити (понимание константности в C ++, как правило, довольно сложно для новых пользователей), проблемы разработки языка (не могут быть выполнены) или просто проблемы приоритетов (дни «неизменности» прошли) ..?

неreadonly Ключевое слово обрабатывает ваши требования? Steve B
Вы в основном спрашиваете «почему у языка нет функции X» - просто: либо она не была предложена + не рассмотрена + не утверждена + не определена + разработана + не реализована + не реализована + не проверена + не документирована + не развернута (сопоставлена с другими возможными вариантами использования для этого ресурс, и влияние распространения языка), илинескольк это было рассмотрено и было отклонено как нежелательное или отложенное. Это не автоматически, что каждый язык получает все мыслимые возможности. Marc Gravell♦
Я понимаю, что реализация материалов стоит дорого, и я понимаю, что другие функции могут иметь более высокий приоритет. Я просто пытался понять последствия реализации такой функции, и почему это было бы так дорого и (возможно) не достаточно значительным .. cwap
Упс, плохо ... Я тоже много думал о readonly, но забыл опубликовать. Обновлю мой мыслительный процесс .. cwap
@ Адам, действительно, «потому что не хватило времени, чтобы сделать разрез» - разумное первое предположение. Эрик Липперт также добавляет заметки здесь. Marc Gravell♦

Ваш Ответ

6   ответов
3

что CLR не нужно менять, но учтите, что не существует стандартного способа выразить это "постоянство" в скомпилированных сборках - и что эти сборки в любом случае могут не использоваться кодом C #. Это не то, что вы можететолько чт сделать для C # - вам придется сделать это для всех языков .NET.

24

C # не поддерживает const, потому что CLR не поддерживает его вообще. CLR не поддерживает его, потому что он не совместим с CLS.

Есть очень мало языков, которые имеют эту концепцию. Язык C имеет поддержку const, которая хорошо поддерживается в C # @ Только для чтен ключевое слово. Но большая собака, конечно, C ++, которая имеет гораздо более широкое применение для const, без сомнения, тот, который вы ищете. Я постараюсь не определять, что должно означать const, это червоточина сама по себе, а просто говорить о «const-ness», свойстве применения const.

Проблема константности в том, что она должна быть @ Насильственн. Это проблема в C #, когда произвольныйДруги language может использовать класс C # и полностью игнорировать постоянство только потому, что язык его не поддерживает. Привязывать его к любому другому языку CLS только потому, что его поддерживает C #, конечно, очень непрактично.

Enforceability - это проблема и в C ++. Потому что язык также поддерживает const_cast <>. Любой клиентский код может быстро и недиагностично отбросить константу. Вы не должны, но иногда вы должны. Потому что есть два вида постоянства, строгое и наблюдаемое. Примерно аналогично частному и общему. Изменяемыеозже ключевое слово @ было добавлено к языку, чтобы попытаться справиться с необходимостью наблюдаемой константности, чтобы, по крайней мере, избежать неизбежного использования const_cast <>. Некоторые люди говорят, что C ++ - сложный язык. Не много слышу о C #.

Лучший ответ на все из них. Большое спасибо, имеет большой смысл! cwap
2

const означает разные вещи в C # по сравнению с C ++.

В C # вы можете использоватьreadonly ключевое слово, чтобы получить необходимый уровень функциональностиconst.

1

Такой класс может быть заполнен только во время сборки, поэтому нам нужен конструктор, чтобы получить int

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

Я не могу говорить за дизайнеров языка C #, но, возможно, причина отсутствияconst применяется ко многим другим конструкциям, потому что его добавление не стоило усилий, и вы можете обойти проблему другими способами (как описано выше и в других ответах / комментариях).

2

Однажды меня удивила следующая ситуация:

class Vector
{
    private double[] m_data;
    public int Dimension {get;set;}

    public double this[int i]
    {
        get {return m_data[i];}
        set {m_data[i] = value;}
    }

    public Vector(int n)
    {
        this.Dimension = n;
        this.m_data = new double(n);
    }

    public static Vector Zero(int n)
    {
        Vector v = new Vector(n);
        for (int i = 0; i < n; i++)
        {
            v[i] = 0.0;
        }

        return v;
     }

    public static readonly Vector Zero3 = Zero(3);
}

Thou Vector.Zero3 только для чтения, и вы не можете назначить ему, вы все равно можете получить доступ к его компоненту, и тогда произойдет следующая глупость:

Vector a = Vector.Zero3;
a[0]     = 2.87;

и сейчас, так какa ничего, кроме ссылки на Vector.Vector3, последний также имеет Vector.Vector3 [0] == 2.87!

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

На самом деле, в классе, который, как я предполагаю, генерирует статические «только для чтения» «константы», я ввел логический флаг:

class Vector
{
    private double[] m_data;
    public int Dimension {get;set;}
    private bool m_bIsConstant = false;
    ...

    public double this[int i]
    {
        get {return m_data[i];}
        set 
        {
           if (!m_bIsConstant)
           {
                m_data[i] = value;
           }
        }
    }
    ...
    public static Vector Zero(int n)
    {
        Vector v = new Vector(n);
        for (int i = 0; i < n; i++)
        {
            v[i] = 0.0;
        }

        v.m_bIsConstant = true;
        return v;
     }
     ...
}

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

1

const ключевое слово было бы особенно полезно.

Ваш первый пример может быть юридически переписан как

public class NumberContainer
{
    private readonly int number;

    public NumberContainer(int number)
    {
        this.number = number;
    }

    public int Number
    {
        get { return number; }
    }
}

Возможно, если компилятор не сможет определить неизменность этого класса (я не знаю), какой-нибудь атрибут может быть полезен?

Во втором примере я не понимаю, к чему ты клонишь. Если функция возвращает постоянное значение, ее можно заменить постоянным полем.

Похожие вопросы