#c# #.net #optimization #language-lawyer
Вопрос:
Хотел задать пару вопросов о том, как платформа .NET обрабатывает статические переменные во время выполнения в своей внутренней работе.
Примечание: Это сделано в образовательных целях, а не из-за проблем с производительностью.
Учитывая три приведенных ниже определения переменных:
using System;
public static class UserProperties
{
public static Guid UserId1 { get { return new Guid("00000000-0000-0000-0000-000000000001"); } }
public static Guid UserId2 { get; } = Guid.Parse("00000000-0000-0000-0000-000000000001");
public static readonly Guid UserId3 = Guid.Parse("00000000-0000-0000-0000-000000000001");
}
Во-первых: насколько я понимаю, в использовании UserId2
over есть преимущество UserId1
, поскольку он не создает новый Guid
экземпляр при каждом доступе к свойству, а вместо этого присваивает один экземпляр резервному полю, которое поддерживается до тех пор, пока программа запущена. Правильно ли это понимание?
Во-вторых: Есть ли какая-то польза в использовании UserId3
сверх UserId2
? Я подозреваю, что так оно и будет, поскольку первое само по себе является полем, а второе-это свойство auto, которое, как я думаю, вызывает метод каждый раз, когда на него ссылаются, но я не уверен в этом.
И последнее: если действительно существуют различия (которые, да, незначительны в данном конкретном примере, но все же), являются ли они несуществующими в результате оптимизации, т. Е. Выдает ли компилятор или JIT одни и те же инструкции?
Спасибо!
Комментарии:
1. p.s. Не смог придумать лучшего названия; любой может предложить свои предложения.
2. Ваше понимание выглядит правильным. Что касается оптимизации — первая не может быть сведена к остальным, так как она возвращает новый экземпляр Guid при каждом вызове. Однако второй, скорее всего, будет встроен JIT-компилятором (на каждом сайте вызовов), чтобы быть таким же, как третий. Самое важное различие между 2 и 3 заключается в том, что 2 позволяет позже изменять логику геттера, не нарушая (сторонний) код, используя его. На 3 нет «геттера», поэтому это невозможно сделать, не перейдя с поля на свойство (разрывное изменение).
3. В сборке выпуска
UserId2
будет встроен в то же,UserId3
что и так, без разницы4. Почему бы не сравнить яблоки с яблоками и не сделать
return Guid.Parse();
?