Question Comment attribuer une valeur par défaut à une propriété Auto C #?


Comment attribuer une valeur par défaut à une propriété Auto C #? J'utilise le constructeur ou je reviens à l'ancienne syntaxe.

 Utilisation du constructeur:

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

Utilisation de la syntaxe de propriété normale  (avec une valeur par défaut)

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

Y a-t-il un meilleur moyen?


1419
2017-09-02 21:29


origine


Réponses:


En C # 5 et plus tôt, pour donner aux propriétés implémentées automatiquement une valeur par défaut, vous devez le faire dans un constructeur.

La possibilité d'avoir des initialiseurs de propriétés automatiques est incluse depuis C # 6.0. La syntaxe est:

public int X { get; set; } = x; // C# 6 or higher

1574
2017-09-02 21:46



Modifier 1/2/15

Avec C # 6 vous pouvez initialiser directement les auto-propriétés (enfin!), Il y a maintenant d'autres réponses dans le thread qui décrivent cela.

Pour C # 5 et ci-dessous:

Bien que l'utilisation prévue de l'attribut ne soit pas de définir réellement les valeurs des propriétés, vous pouvez utiliser la réflexion pour toujours les définir de toute façon ...

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; }
}

242
2018-06-22 18:14



Lorsque vous insérez une valeur initiale pour une variable, elle sera implicitement exécutée dans le constructeur.

Je dirais que cette syntaxe était la meilleure pratique en C # jusqu'à 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; }
}

Comme cela vous donne un contrôle clair de l'ordre des valeurs sont affectées.

À partir de C # 6, il y a une nouvelle façon:

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

128
2017-09-04 12:16



DefaultValueAttribute fonctionne UNIQUEMENT dans le concepteur vs. Il n'initialisera pas la propriété à cette valeur.

Voir L'attribut DefaultValue ne fonctionne pas avec ma propriété Auto


73
2017-09-02 22:44



Parfois je l'utilise, si je ne veux pas que ce soit réellement défini et persiste dans mon db:

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

        set { _name = value; } 
    }
}

Évidemment, si ce n'est pas une chaîne, je peux rendre l'objet Nullable (double ?, int?) Et vérifier si elle est nulle, retourner une valeur par défaut, ou retourner la valeur à laquelle elle est définie.

Ensuite, je peux faire une vérification dans mon dépôt pour voir si c'est mon défaut et ne pas persister, ou faire une vérification backdoor pour voir le vrai statut de la valeur de sauvegarde, avant de sauvegarder.

J'espère que cela pourra aider!


48
2017-09-02 23:07



À partir de C # 6.0, Nous pouvons attribuer une valeur par défaut aux propriétés implémentées automatiquement.

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

Nous pouvons également créer des propriétés implémentées automatiquement en lecture seule comme:

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

Voir: C # 6: Premières réactions, initialisateurs pour les propriétés implémentées automatiquement - Par Jon Skeet


23
2018-04-29 14:40



En C # 6.0 c'est un jeu d'enfant!

Vous pouvez le faire dans le Class déclaration elle-même, dans les déclarations de déclaration de propriété.

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;
    }
}

17
2017-07-25 19:35



petit échantillon complet:

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
2018-06-17 07:44



En version de C # (6.0) et plus, tu peux faire :

Pour les propriétés Readonly

public int ReadOnlyProp => 2;

Pour les propriétés à la fois lisibles et lisibles

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

Dans la version actuelle de C # (7.0), vous pouvez faire: (L'extrait montre plutôt comment vous pouvez utiliser des accesseurs get / set d'expression de corps à faire est plus compact lors de l'utilisation avec des champs de sauvegarde)

private string label = "Default Value";

// Expression-bodied get / set accessors.
public string Label
{
   get => label;
   set => this.label = value; 
 }

11
2018-03-15 01:07



Ma solution consiste à utiliser un attribut personnalisé qui fournit une initialisation de propriété de valeur par défaut par une constante ou en utilisant un initialiseur de type de propriété.

[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];
    }
}

Pour utiliser cet attribut, il est nécessaire d'hériter d'une classe à partir d'un initialiseur de classe de base spécial ou d'utiliser une méthode d'aide statique:

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);
        }
    }
}

Exemple d'utilisation:

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);
}

Sortie:

Item1
(X=3,Y=4)
StringValue

9
2018-01-17 22:04