Pertanyaan Bagaimana Anda memberi C # Auto-Property nilai default?


Bagaimana Anda memberi C # Auto-Property nilai default? Saya juga menggunakan konstruktor, atau kembali ke sintaks yang lama.

 Menggunakan Pembuat:

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

Menggunakan sintaks properti normal  (dengan nilai default)

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

Apakah ada cara yang lebih baik?


1419
2017-09-02 21:29


asal


Jawaban:


Dalam C # 5 dan sebelumnya, untuk memberikan properti yang diimplementasikan otomatis sebagai nilai default, Anda harus melakukannya dalam konstruktor.

Kemampuan untuk memiliki initializers properti otomatis disertakan sejak C # 6.0. Sintaksnya adalah:

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

1574
2017-09-02 21:46



Edit 1/2/15

Dengan C # 6 Anda dapat menginisialisasi properti otomatis secara langsung (akhirnya!), Sekarang ada jawaban lain di utas yang menjelaskan itu.

Untuk C # 5 dan di bawah:

Meskipun penggunaan atribut yang dimaksudkan bukan untuk benar-benar mengatur nilai properti, Anda dapat menggunakan refleksi untuk selalu mengaturnya ...

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



Ketika Anda sebaris nilai awal untuk variabel itu akan dilakukan secara implisit di konstruktor.

Saya berpendapat bahwa sintaks ini adalah praktik terbaik dalam C # hingga 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; }
}

Karena ini memberi Anda kontrol yang jelas terhadap nilai pesanan yang ditetapkan.

Pada C # 6 ada cara baru:

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

128
2017-09-04 12:16



DefaultValueAttribute HANYA berfungsi di perancang vs. Itu tidak akan menginisialisasi properti ke nilai itu.

Lihat Atribut DefaultValue tidak berfungsi dengan Properti Otomatis saya


73
2017-09-02 22:44



Kadang-kadang saya menggunakan ini, jika saya tidak ingin itu benar-benar diatur dan bertahan di db saya:

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

        set { _name = value; } 
    }
}

Tentunya jika itu bukan string maka saya mungkin membuat objek nullable (double ?, int?) Dan memeriksa apakah itu null, mengembalikan default, atau mengembalikan nilai yang ditetapkan.

Kemudian saya dapat melakukan pemeriksaan di repositori saya untuk melihat apakah itu default saya dan tidak berlanjut, atau membuat backdoor check in untuk melihat status sebenarnya dari nilai backing, sebelum menyimpan.

Semoga itu membantu!


48
2017-09-02 23:07



Dimulai dengan C # 6.0, Kita dapat menetapkan nilai default ke properti yang diimplementasikan secara otomatis.

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

Kami juga dapat membuat properti yang diimplementasikan otomatis hanya-baca seperti:

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

Lihat: C # 6: Reaksi pertama, Initializers untuk properti yang diimplementasikan secara otomatis - Oleh Jon Skeet


23
2018-04-29 14:40



Di C # 6.0 ini sangat mudah!

Anda dapat melakukannya di Class deklarasi itu sendiri, dalam pernyataan deklarasi properti.

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



sedikit contoh lengkap:

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



Dalam Versi C # (6.0) & lebih besar, Anda dapat melakukan :

Untuk properti Hanya Baca

public int ReadOnlyProp => 2;

Untuk properti Writable & Readable

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

Versi terbaru dari C # (7.0), Anda dapat melakukan: (Potongan sedikit menampilkan bagaimana Anda dapat menggunakan ekspresi get / set accessor berbadan untuk membuat lebih kompak ketika menggunakan dengan bidang backing)

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



Solusi saya adalah menggunakan atribut khusus yang memberikan inisialisasi properti nilai default dengan konstan atau menggunakan penginisialisasi jenis properti.

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

Untuk menggunakan atribut ini perlu mewarisi kelas dari kelas dasar-penginisialisasi khusus atau menggunakan metode pembantu statis:

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

Contoh penggunaan:

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

Keluaran:

Item1
(X=3,Y=4)
StringValue

9
2018-01-17 22:04



Selain jawabannya sudah diterima, untuk skenario ketika Anda ingin mendefinisikan properti default sebagai fungsi dari properti lain yang dapat Anda gunakan ekspresi notasi tubuh pada C # 6.0 (dan lebih tinggi) untuk konstruksi yang lebih elegan dan ringkas seperti:

public class Person{

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

    public string First { get; set; } = "First";
    public string Last { get; set; } = "Last";
}

Anda dapat menggunakan hal di atas dengan cara berikut

    var p = new Person();

    p.FullName; // First Last

    p.First = "Jon";
    p.Last = "Snow";

    p.FullName; // Jon Snow

Agar dapat menggunakan notasi "=>" di atas, properti harus dibaca saja, dan Anda tidak menggunakan kata kunci accessor get.

Detail tentang MSDN


8
2017-10-30 02:16