Подтвердить что ты не робот

Можно ли использовать общедоступную переменную в С#, если она только для чтения?

Есть ли какая-то внутренняя разница между синтаксическим сахаром С# для создания свойств:

public string FirstName { get; set; }

и просто сделать общедоступные переменные следующим образом:

public string LastName;

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

public readonly string InternalCode;

Это лучший способ создания свойства readonly?

using System;

namespace TestProps
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            customer.FirstName = "Jim";
            customer.LastName = "Smith";
            customer.Show();
        }
    }

    class Customer
    {
        public string FirstName { get; set; } //prefered
        public string LastName; //avoid
        public readonly string InternalCode; //???

        public Customer()
        {
            InternalCode = "234729834723984";
        }

        public void Show()
        {
            Console.WriteLine("{0}, {1} ({2})", LastName, FirstName, InternalCode);
            Console.ReadLine();
        }
    }
}
4b9b3361

Ответ 1

Так как он не ответил (пока), и никто еще не ссылался на это еще: есть замечательная статья на эту тему, Джон Скит, вносящий изменения в свою книгу С# в глубину (дайте кредиты Джону):

Почему свойство Свойства

Ответ 2

Использование свойства предоставляет интерфейс, который более устойчив к изменениям в будущем. Скажем, некоторое время в будущем, принято решение добавить префикс к внутреннему коду.

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

Используя свойство, вы можете просто написать следующие

public string InternalCode { 
    get { return _prefix + _internalCode; } 
}

и все готово!

Ответ 3

По-моему, нормально показывать публичные поля (особенно, если они только для чтения или const). Сказав это, я бы сказал, что в примере, который вы представляете, я бы, вероятно, пошел со свойствами, так как они предоставят вам 2 преимущества (над полями): 1) лучшее инкапсулирование и может позволить вам адаптировать ваш код в будущее и 2) если вы выполняете привязку данных, тогда вам нужны свойства.

Ответ 4

Да. это нормально, чтобы иметь общедоступные переменные readonly (это просто, что они могут быть инициализированы во время определения или конструктора).

например. Decimal.MaxValue

Наличие открытого свойства readonly является хорошим, если изменяется значение поддержки (отличное от того, с чем оно было инициализировано).

например. Environment.TickCount

Я думал, что Environment.NewLine будет публичной переменной readonly. Ну, это общедоступная собственность (получить только), и причина может заключаться в поддержании совместимости на разных платформах.

Ответ 5

Короткий ответ: public const в порядке, public readonly не обязательно, public get без набора не обязательно. Объекты, которые нельзя изменить без назначения, могут быть в порядке. Типы ссылок опасны, так как вы все равно можете изменить их значения, даже если вы не можете изменить саму ссылку.

Проблема с ключевым словом readonly заключается в том, что это не значит, что вы понимаете как логически readonly/immutable. Это значит, что "может быть назначен только в конструкторе". Ссылки не могут быть изменены, но его значения могут быть изменены. К сожалению, нет "реального" ключевого слова readonly, предоставленного С#. См. Также https://blogs.msdn.microsoft.com/ericlippert/2007/11/13/immutability-in-c-part-one-kinds-of-immutability/

Свойства не могут иметь ключевое слово readonly (https://titombo.wordpress.com/2012/11/11/using-the-c-modifiers/). Как уже отмечалось, вы можете использовать свойство и определять только get и no set, хотя вы не можете установить это свойство в конструкторе. Используя частный набор, вы можете установить свойство из annywhere в классе, а не только в конструкторе. Поле readonly будет немного более ограничительным.