Иллюстрирование использования энергозависимого ключевого слова в C#

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

87
задан yoozer8 29 May 2012 в 17:43
поделиться

4 ответа

Я получил рабочий пример!

Основная идея получена из вики, но с некоторыми изменениями для C #. Статья в вики демонстрирует это для статического поля C ++, похоже, что C # всегда тщательно компилирует запросы к статическим полям ... и я приведу пример с нестатическим полем:

Если вы запустите этот пример в Release ] и без отладчика (т.е. используя Ctrl + F5), то строка while (test.foo! = 255) будет оптимизирована до 'while (true)', и эта программа никогда возвращается. Но после добавления ключевого слова volatile вы всегда получаете «ОК».

class Test
{
    /*volatile*/ int foo;

    static void Main()
    {
        var test = new Test();

        new Thread(delegate() { Thread.Sleep(500); test.foo = 255; }).Start();

        while (test.foo != 255) ;
        Console.WriteLine("OK");
    }
}
101
ответ дан 24 November 2019 в 07:50
поделиться

Да, это аппаратно-зависимо (Вы вряд ли будете видеть проблему без нескольких процессоров), но это является также зависящим от реализации. Спецификации модели памяти в спецификации CLR разрешают вещи, которые реализацию Microsoft CLR не обязательно делают. Лучшая документация, которую я видел на энергозависимом ключевом слове, это сообщение в блоге Joe Duffy . Обратите внимание, что он говорит, что документация MSDN является "очень вводящей в заблуждение".

21
ответ дан Craig Stuntz 24 November 2019 в 07:50
поделиться

Это не действительно вопрос случая отказа, когда 'энергозависимое' ключевое слово не определяется, больше что ошибка могла произойти, когда это не было определено. Обычно Вы собираетесь знать когда дело обстоит так лучше, чем компилятор!

самый легкий образ мыслей об этом был бы то, что компилятор, если это хотело, мог бы встроить определенные значения. Путем маркировки значения как энергозависимое, Вы говорите себе и компилятору, что значение может на самом деле измениться (даже если компилятор не думает так). Это означает, что компилятор не должен встраивать значения, сохранить кэш или считать значение рано (в попытке оптимизировать).

Это поведение не является действительно тем же ключевым словом как в C++.

MSDN имеет краткое описание здесь . Вот, возможно, больше подробно сообщение на предметах Энергозависимость, Атомарность и Взаимная блокировка

6
ответ дан Ray Hayes 24 November 2019 в 07:50
поделиться

Трудно продемонстрировать в C#, поскольку код абстрагирован виртуальной машиной, таким образом на одной реализации этой машины это работает правильно без энергозависимого, в то время как это могло бы перестать работать на другом.

Википедия имеет хороший пример, как продемонстрировать его в C, все же.

то же самое могло произойти в C#, если JIT-компилятор решает, что значение переменной не может измениться так или иначе и таким образом создает машинный код, который даже не проверяет его больше. Если бы теперь другой поток изменял значение, Ваш первый поток мог бы все еще быть пойман в цикле.

Другим примером является Активное ожидание.

Снова, это могло произойти с C# также, но он сильно зависит от виртуальной машины и от JIT-компилятора (или интерпретатор, если он не имеет никакого JIT... в теории, я думаю, что MS всегда использует JIT-компилятор и также Моно использование один; но Вы могли бы быть в состоянии отключить его вручную).

4
ответ дан Mecki 24 November 2019 в 07:50
поделиться
Другие вопросы по тегам:

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