2339 Stimmen

Was ist der beste Weg, um eine C# Auto-Eigenschaft einen Anfangswert zu geben?

Wie gibt man einer C#-Auto-Eigenschaft einen Anfangswert?

Entweder verwende ich den Konstruktor, oder ich greife auf die alte Syntax zurück.

Verwendung des Konstruktors:

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

Verwendung der normalen Eigenschaftssyntax (mit einem Anfangswert)

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

Gibt es einen besseren Weg?

12voto

ghiboz Punkte 7619

Wenig vollständige Stichprobe:

using System.ComponentModel;

private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
    get { return bShowGroup; }
    set { bShowGroup = value; }
}

36 Stimmen

Das wird nicht funktionieren. DefaultValueAttribute ist nur ein Hinweis auf die Serialisierung, es wird nicht ShowGroup à true denn der Standardwert für jeden booleschen Wert ist false .

0 Stimmen

Dies ist keine Auto-Eigenschaft.

12voto

introspected Punkte 159

Meine Lösung ist ein benutzerdefiniertes Attribut zu verwenden, die Standardwert Eigenschaft Initialisierung durch Konstante oder mit Eigenschaft Typ Initialisierer bietet.

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

Um dieses Attribut zu verwenden, muss eine Klasse von einem speziellen Basisklassen-Initialisierer geerbt oder eine statische Hilfsmethode verwendet werden:

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

Beispiel für die Verwendung:

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

Ausgabe:

Item1
(X=3,Y=4)
StringValue

2 Stimmen

Wie oben erwähnt, mit Reflexion zu initialisieren Standardwerte ist sowohl langsam und Overkill. Initialisieren Sie auf den Konstruktor, verwenden Sie eine nicht auto Eigenschaft oder auf c# 6 und höher, verwenden Sie die vereinfachte Notation in der akzeptierten Antwort gezeigt

0 Stimmen

Wann ist es besser, diese Option zu nutzen als die anderen hier genannten Möglichkeiten?

9voto

SUNIL DHAPPADHULE Punkte 2413

Sie können einfach so formulieren

public sealed  class Employee
{
    public int Id { get; set; } = 101;
}

7voto

RayLoveless Punkte 17624

Im Konstruktor. Der Zweck des Konstruktors besteht darin, seine Datenelemente zu initialisieren.

6voto

ComeIn Punkte 1393
private string name;
public string Name 
{
    get 
    {
        if(name == null)
        {
            name = "Default Name";
        }
        return name;
    }
    set
    {
        name = value;
    }
}

2 Stimmen

Ich denke, der Fragesteller wollte eine Auto-Eigenschaft, d.h. eine nicht-abstrakte Eigenschaft in einer Klasse oder Struktur, bei der man nur get; mit einem Semikolon (oft kombiniert mit set; ), um anzugeben, dass der Compiler den Körper der get Accessor automatisch.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X