Как вы даете C-Auto-свойство значение по умолчанию?

Как задать для свойства C # Auto-Property значение по умолчанию? Я либо использую конструктор, либо возвращаюсь к старому синтаксису.

Использование конструктора:

class Person 
{
    public Person()
    {
        Name = "Default Name";
    }
    public string Name { get; set; }
}

Использование обычного синтаксиса свойства (со значением по умолчанию)

private string name = "Default Name";
public string Name 
{
    get 
    {
        return name;
    }
    set
    {
        name = value;
    }
}

Есть ли лучший способ?

вопрос задан 2.09.2008
bentford
16397 репутация

21 ответов


  • 0 рейтинг

    Пытались ли вы использовать DefaultValueAttribute или Должны ли методы Serialize и Reset в сочетании с конструктором? Мне кажется, что один из этих двух методов необходим, если вы создаете класс, который может отображаться на поверхности конструктора или в сетке свойств.

    ответ дан OwenP, с репутацией 17276, 2.09.2008
  • 0 рейтинг

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

    ответ дан dbobrowski, с репутацией 515, 13.09.2012
  • 0 рейтинг

    Я думаю, что это сделало бы это для ya givng SomeFlag по умолчанию false.

    private bool _SomeFlagSet = false;
    public bool SomeFlag
    {
        get
        {
            if (!_SomeFlagSet)
                SomeFlag = false;        
    
            return SomeFlag;
        }
        set
        {
            if (!_SomeFlagSet)
                _SomeFlagSet = true;
    
            SomeFlag = value;        
        }
    }
    
    ответ дан user3076134, с репутацией 13, 6.12.2013
  • 0 рейтинг

    маленький полный образец:

    using System.ComponentModel;
    
    private bool bShowGroup ;
    [Description("Show the group table"), Category("Sea"),DefaultValue(true)]
    public bool ShowGroup
    {
        get { return bShowGroup; }
        set { bShowGroup = value; }
    }
    
    ответ дан ghiboz, с репутацией 3915, 17.06.2010
  • 0 рейтинг

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

    @Darren Kopp - хороший ответ, чистый и правильный. И, повторюсь, вы МОЖЕТЕ написать конструкторы для абстрактных методов. Вам просто нужно получить к ним доступ из базового класса при написании конструктора:

    Конструктор в базовом классе:

    public BaseClassAbstract()
    {
        this.PropertyName = "Default Name";
    }
    

    Конструктор на Производный / Бетон / Подкласс:

    public SubClass() : base() { }
    

    Дело в том, что переменная экземпляра, извлеченная из базового класса, может похоронить имя вашего базового поля. Установка текущего значения экземпляра объекта с помощью «this». "позволит вам правильно сформировать ваш объект относительно текущего экземпляра и требуемых уровней разрешений (модификаторов доступа), где вы его создаете.

    ответ дан Zack Jannsen, с репутацией 482, 31.07.2012
  • 0 рейтинг

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

    Возможность иметь авто инициализаторы свойств включена начиная с C # 6. 0. Синтаксис:

    public int X { get; set; } = x; // C# 6 or higher
    
    ответ дан Darren Kopp, с репутацией 56796, 2.09.2008
  • 0 рейтинг

    В версии C # (6. 0) & amp; больше , вы можете сделать:

    Для Readonly свойств

    public int ReadOnlyProp => 2;
    

    Для обоих записываемых и amp; Читаемые свойства

    public string PropTest { get; set; } = "test";
    

    В текущей версии C # (7. 0) , вы можете сделать: (Фрагмент скорее показывает, как вы можете использовать выражения get / set с выражением body, чтобы сделать его более компактным при использовании с вспомогательными полями)

    private string label = "Default Value";
    
    // Expression-bodied get / set accessors.
    public string Label
    {
       get => label;
       set => this.label = value; 
     }
    
    ответ дан ANewGuyInTown, с репутацией 1888, 15.03.2017
  • 0 рейтинг

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

    Я бы сказал, что этот синтаксис был лучшей практикой в ​​C # до 5:

    class Person 
    {
        public Person()
        {
            //do anything before variable assignment
    
            //assign initial values
            Name = "Default Name";
    
            //do anything after variable assignment
        }
        public string Name { get; set; }
    }
    

    Поскольку это дает вам четкий контроль над назначенными значениями заказа.

    Начиная с C # 6 появился новый путь:

    public string Name { get; set; } = "Default Name"
    
    ответ дан Keith, с репутацией 88871, 4.09.2008
  • 0 рейтинг

    В дополнение к уже принятому ответу для сценария, когда вы хотите определить свойство по умолчанию как функцию , других свойств, вы можете использовать нотацию тела выражения на C # 6. 0 (и выше) для еще более элегантных и лаконичных конструкций, таких как:

    public class Person{
    
        public string FullName  => $"{First} {Last}"; // expression body notation
    
        public string First { get; set; } = "First";
        public string Last { get; set; } = "Last";
    }
    

    Вы можете использовать вышеуказанное следующим образом

        var p = new Person();
    
        p.FullName; // First Last
    
        p.First = "Jon";
        p.Last = "Snow";
    
        p.FullName; // Jon Snow
    

    Для того, чтобы иметь возможность использовать выше "= & gt;" примечание, свойство должно быть только для чтения, и вы не используете ключевое слово get accessor.

    Подробности на MSDN

    ответ дан brakeroo, с репутацией 517, 30.10.2016
  • 0 рейтинг

    DefaultValueAttribute работает ТОЛЬКО в конструкторе. Это не будет инициализировать свойство к этому значению.

    См. Атрибут DefaultValue не работает с моим автоматическим свойством

    ответ дан Darren Kopp, с репутацией 56796, 2.09.2008
  • 0 рейтинг

    В C # 6 и выше вы можете просто использовать синтаксис:

    public object Foo { get; set; } = bar;
    

    Обратите внимание, что для свойства readonly просто опустите набор, например:

    public object Foo { get; } = bar;
    

    Вы также можете назначить readonly авто-свойств из конструктора.

    До этого я отвечал как ниже.

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

    Еще один вариант - сделать то, что ASP. Net делает и определяет значения по умолчанию через атрибут:

    http: // msdn. Microsoft. ком / EN-US / библиотека / система. componentmodel. defaultvalueattribute. aspx

    ответ дан Lex, с репутацией 515, 4.09.2008
  • 0 рейтинг

    В C # 6. 0 это бриз!

    Вы можете сделать это в самом объявлении Class, в заявлениях объявления свойства.

    public class Coordinate
    { 
        public int X { get; set; } = 34; // get or set auto-property with initializer
    
        public int Y { get; } = 89;      // read-only auto-property with initializer
    
        public int Z { get; }            // read-only auto-property with no initializer
                                         // so it has to be initialized from constructor    
    
        public Coordinate()              // .ctor()
        {
            Z = 42;
        }
    }
    
    ответ дан Shiva, с репутацией 13320, 25.07.2016
  • 0 рейтинг

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

    class Person
    {
        private string _name; 
        public string Name 
        { 
            get 
            {
                return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
            } 
    
            set { _name = value; } 
        }
    }
    

    Очевидно, что если это не строка, я мог бы сделать объект обнуляемым (double? инт? ) и проверьте, имеет ли оно значение null, верните значение по умолчанию или верните значение, на которое оно установлено.

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

    Надеюсь, что помогает!

    ответ дан crucible, с репутацией 2061, 2.09.2008
  • 0 рейтинг
    public Class ClassName{
        public int PropName{get;set;}
        public ClassName{
            PropName=0;  //Default Value
        }
    }
    
    ответ дан FloodMoo, с репутацией 21, 4.09.2014
  • 0 рейтинг

    Начиная с C # 6. 0 , Мы можем назначить значение по умолчанию для автоматически реализуемых свойств.

    public string Name { get; set; } = "Some Name";
    

    Мы также можем создать автоматически реализованное свойство только для чтения, например:

    public string Name { get; } = "Some Name";
    

    См .: C # 6: Первые реакции, Инициализаторы для автоматически реализуемых свойств - По Джону Скиту

    ответ дан Habib, с репутацией 176355, 29.04.2014
  • 0 рейтинг

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

    Хм. , , возможно это будет предметом его собственного вопроса позже

    ответ дан Joel Coehoorn, с репутацией 299287, 3.09.2008
  • 0 рейтинг

    В конструкторе. Цель конструктора - инициализировать его элементы данных.

    ответ дан RayLoveless, с репутацией 7132, 18.07.2016
  • 0 рейтинг

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

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class InstanceAttribute : Attribute
    {
        public bool IsConstructorCall { get; private set; }
        public object[] Values { get; private set; }
        public InstanceAttribute() : this(true) { }
        public InstanceAttribute(object value) : this(false, value) { }
        public InstanceAttribute(bool isConstructorCall, params object[] values)
        {
            IsConstructorCall = isConstructorCall;
            Values = values ?? new object[0];
        }
    }
    

    Чтобы использовать этот атрибут, необходимо унаследовать класс от специального базового инициализатора класса или использовать статический вспомогательный метод:

    public abstract class DefaultValueInitializer
    {
        protected DefaultValueInitializer()
        {
            InitializeDefaultValues(this);
        }
    
        public static void InitializeDefaultValues(object obj)
        {
            var props = from prop in obj.GetType().GetProperties()
                        let attrs = prop.GetCustomAttributes(typeof(InstanceAttribute), false)
                        where attrs.Any()
                        select new { Property = prop, Attr = ((InstanceAttribute)attrs.First()) };
            foreach (var pair in props)
            {
                object value = !pair.Attr.IsConstructorCall && pair.Attr.Values.Length > 0
                                ? pair.Attr.Values[0]
                                : Activator.CreateInstance(pair.Property.PropertyType, pair.Attr.Values);
                pair.Property.SetValue(obj, value, null);
            }
        }
    }
    

    Пример использования:

    public class Simple : DefaultValueInitializer
    {
        [Instance("StringValue")]
        public string StringValue { get; set; }
        [Instance]
        public List Items { get; set; }
        [Instance(true, 3,4)]
        public Point Point { get; set; }
    }
    
    public static void Main(string[] args)
    {
        var obj = new Simple
            {
                Items = {"Item1"}
            };
        Console.WriteLine(obj.Items[0]);
        Console.WriteLine(obj.Point);
        Console.WriteLine(obj.StringValue);
    }
    

    Выход:

    Item1
    (X=3,Y=4)
    StringValue
    
    ответ дан introspected, с репутацией 129, 17.01.2013
  • 0 рейтинг

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

    ответ дан Preet Singh, с репутацией 1186, 11.01.2016
  • 0 рейтинг

    Редактировать 1/2/15

    С C # 6 вы можете инициализировать авто-свойства напрямую (наконец-то! ), теперь есть другие ответы в теме, которые описывают это.

    Для C # 5 и ниже:

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

    public class DefaultValuesTest
    {    
        public DefaultValuesTest()
        {               
            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
            {
                DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
    
                if (myAttribute != null)
                {
                    property.SetValue(this, myAttribute.Value);
                }
            }
        }
    
        public void DoTest()
        {
            var db = DefaultValueBool;
            var ds = DefaultValueString;
            var di = DefaultValueInt;
        }
    
    
        [System.ComponentModel.DefaultValue(true)]
        public bool DefaultValueBool { get; set; }
    
        [System.ComponentModel.DefaultValue("Good")]
        public string DefaultValueString { get; set; }
    
        [System.ComponentModel.DefaultValue(27)]
        public int DefaultValueInt { get; set; }
    }
    
    ответ дан Chuck Rostance, с репутацией 4729, 22.06.2011
  • 0 рейтинг
    class Person 
    {    
        /// Gets/sets a value indicating whether auto 
        /// save of review layer is enabled or not
        [System.ComponentModel.DefaultValue(true)] 
        public bool AutoSaveReviewLayer { get; set; }
    }
    
    ответ дан Nag, с репутацией 99, 26.05.2011