Свойство детерминизма - PullRequest
       7

Свойство детерминизма

7 голосов
/ 15 сентября 2010

Есть ли какой-либо способ в C # пометить свойство как детерминированное?

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

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

Это что-то, что даже существует, или я держусь за соломинку?

Ответы [ 4 ]

8 голосов
/ 15 сентября 2010

Если свойство простое, например неявное свойство:

public int X { get; set; }

или чтение из локальной переменной:

public int X { get { return _x; } }

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

Я проверил это, сравнив 100 миллионов итераций обращения к свойству десять раз и скопировав свойство в переменную и получив десятьраз, и нет заметной разницы вообще.

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

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

5 голосов
/ 15 сентября 2010

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

Документация Microsoft просто рекомендует не вводить какие-либо побочныеэффекты в ваших геттерах:

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

private int number;
public int Number
{
    get
    {
        return number++;   // Don't do this
    }
}

Как упомянуто Дареном, еще один аспект, который следует учитывать, - это множественныймногопоточность (если ваш объект не является действительно неизменным).Что, если другой поток изменил состояние объекта так, что получатель должен вернуть другое значение при втором вызове?Для компилятора не существует простого способа дать какие-либо гарантии, например, в следующем сценарии:

class List
{
    IList data;

    // called several times on thread A
    // property has no side-effects
    public int Count { get data.Length; }

    // called several times on thread B
    public void Add(object o)
    {
        data.Add(o);
    }
}
2 голосов
/ 15 сентября 2010

Я думаю, вы ищете readonly, однако я не уверен в том, как производительность сравнивается с локальной переменной.И это применимо только к полям, а не к свойствам.

Кроме того, readonly не подразумевает детерминизм.

private readonly List<string> fixedList = new List<string>();

просто означает, что объект fixedList не может быть заменен, но содержимое можетвсе еще будет изменено.

0 голосов
/ 15 сентября 2010

Если поле поддержки вашей собственности не равно readonly, как вы будете учитывать проблемы с потоками?

...