Как вы даете С# Auto-Property значение по умолчанию?

Как вы даете С# 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;
    }
}

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

1568
задан 03 сент. '08 в 0:29
источник поделиться
23 ответов

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

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

public int X { get; set; } = x; // C# 6 or higher
1805
ответ дан 03 сент. '08 в 0:46
источник

Отредактировано 1/2/15

С# 6:

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

С# 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; }
}
257
ответ дан 22 июня '11 в 21:14
источник

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

Я бы сказал, что этот синтаксис был наилучшей практикой в ​​С# до 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; }
}

Так как это дает вам четкое управление значениям порядка.

С С# 6 существует новый способ:

public string Name { get; set; } = "Default Name"
137
ответ дан 04 сент. '08 в 15:16
источник

DefaultValueAttribute ТОЛЬКО работает в дизайнере vs. Он не будет инициализировать свойство для этого значения.

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

76
ответ дан 03 сент. '08 в 1:44
источник

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

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

        set { _name = value; } 
    }
}

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

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

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

50
ответ дан 03 сент. '08 в 2:07
источник

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

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

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

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

Смотрите: С# 6: первые реакции, инициализаторы для автоматически реализованных свойств - Jon Skeet

32
ответ дан 29 апр. '14 в 17:40
источник

В С# 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;
    }
}
29
ответ дан 25 июля '16 в 22:35
источник

В версии С# (6.0) и выше вы можете:

Для свойств Readonly

public int ReadOnlyProp => 2;

Для обоих свойств Writable и Readable

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

В текущей версии С# (7.0) вы можете сделать: (фрагмент скорее показывает, как вы можете использовать выражения с расширенными функциями get/set, чтобы сделать более компактным при использовании с полями поддержки)

private string label = "Default Value";

// Expression-bodied get / set accessors.
public string Label
{
   get => label;
   set => this.label = value; 
 }
17
ответ дан 15 марта '17 в 4:07
источник

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

using System.ComponentModel;

private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
    get { return bShowGroup; }
    set { bShowGroup = value; }
}
11
ответ дан 17 июня '10 в 10:44
источник

В дополнение к уже принятому ответу, для сценария, когда вы хотите определить свойство по умолчанию как функцию от других свойств, вы можете использовать нотацию тела выражения на С# 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

Чтобы использовать вышеуказанную нотацию "=>", свойство должно быть доступно только для чтения, и вы не используете ключевое слово get accessor.

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

10
ответ дан 30 окт. '16 в 5:16
источник

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

[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<string> 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
9
ответ дан 18 янв. '13 в 1:04
источник

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

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

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

public object Foo { get; } = bar;

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

До этого я ответил, как показано ниже.

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

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

http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

7
ответ дан 04 сент. '08 в 20:08
источник

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

4
ответ дан 18 июля '16 в 19:39
источник

Вы пытались использовать DefaultValueAttribute или ShouldSerialize и Reset в сочетании с конструктором? Я чувствую, что один из этих двух методов необходим, если вы создаете класс, который может отображаться на поверхности конструктора или в сетке свойств.

2
ответ дан 03 сент. '08 в 0:32
источник
public Class ClassName{
    public int PropName{get;set;}
    public ClassName{
        PropName=0;  //Default Value
    }
}
2
ответ дан 04 сент. '14 в 23:44
источник
private string name;
public string Name 
{
    get 
    {
        if(name == null)
        {
            name = "Default Name";
        }
        return name;
    }
    set
    {
        name = value;
    }
}
2
ответ дан 01 нояб. '18 в 17:51
источник

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

1
ответ дан 11 янв. '16 в 14:33
источник

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

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

1
ответ дан 03 сент. '08 в 6:43
источник

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

@Даррен Копп - хороший ответ, чистый и правильный. И, повторяю, вы можете написать конструкторы для абстрактных методов. Вам просто нужно получить к ним доступ из базового класса при написании конструктора:

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

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

Конструктор в Derived/Concrete/Sub-Class:

public SubClass() : base() { }

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

1
ответ дан 31 июля '12 в 14:02
источник
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; }
}
0
ответ дан 26 мая '11 в 22:29
источник

Я думаю, что это сделало бы это для 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;        
    }
}
-2
ответ дан 07 дек. '13 в 0:50
источник

Введите Prop и нажмите кнопку "TAB" и Visual Studio. Предложите вам следующий код,

public int MyProperty { get; set; }

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

если вы должны использовать некоторую переменную в другом классе, вы можете использовать как follwing,

public static int MyProperty { get; set; }

в коде вы можете назначить переменную

MyProperty=1;

в другом классе вы можете использовать,

MessageBox.Show(Classname.MyProperty);
-3
ответ дан 05 апр. '17 в 7:12
источник

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

-5
ответ дан 13 сент. '12 в 22:13
источник

Другие вопросы по метке или Задайте вопрос