配列 - get set c#




どのようにC#Auto-Propertyにデフォルト値を与えますか? (15)

どのように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;
    }
}

より良い方法がありますか?


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

C#5以前では、自動実装されたプロパティをデフォルト値にするには、コンストラクタでそれを行う必要があります。

自動プロパティ初期化子を持つ機能は、C#6.0以降に含まれています。 構文は次のとおりです。

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


「コンストラクタが終了したら、構築を終了する必要がある」ため、コンストラクタを使用します。 プロパティはクラスが保持する状態と似ていますが、デフォルトの状態を初期化する必要がある場合は、コンストラクタでその状態を行います。



これは、SomeFlagにfalseのデフォルトを設定している場合に実行されると思います。

private bool _SomeFlagSet = false;
public bool SomeFlag
{
    get
    {
        if (!_SomeFlagSet)
            SomeFlag = false;        

        return SomeFlag;
    }
    set
    {
        if (!_SomeFlagSet)
            _SomeFlagSet = true;

        SomeFlag = value;        
    }
}

コンストラクタで。 コンストラクタの目的は、データメンバを初期化することです。


バージョンC#(6.0)以上では 、次の操作を実行できます。

Readonlyプロパティの場合

public int ReadOnlyProp => 2;

書き込み可能なプロパティと読み取り可能なプロパティの両方

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

C#(7.0)の現在のバージョンでは、次のことができます。(スニペットは、バッキングフィールドを使用する場合、式ボディのget / setアクセサを使用してコンパクトにする方法を表示します)

private string label = "Default Value";

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

初期化のためにコンストラクタを使用して行を初期化することは悪い習慣であり、後でさらに大きな変更をもたらすでしょう。


変数の初期値をインライン化すると、それはコンストラクタで暗黙的に行われます。

私は、この構文は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"

既定のプロパティを他のプロパティの関数として定義する場合は、既に受け入れられている回答に加えて、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

上記の "=>"表記法を使用できるようにするには、プロパティーは読み取り専用で、get accessorキーワードは使用しないでください。

MSDN詳細


明確にするために、はい、クラス派生オブジェクトのコンストラクタにデフォルト値を設定する必要があります。 コンストラクターが使用されている場合は、適切なアクセス修飾子を使用してコンストラクターが存在することを確認する必要があります。 オブジェクトがインスタンス化されていない場合、例えばコンストラクタがない場合(静的メソッドなど)は、デフォルト値をフィールドで設定できます。 ここでの推論は、オブジェクト自体が一度だけ作成され、インスタンス化しないということです。

@ダーレンKopp - 良い答え、きれいで、正しい。 また、繰り返して言うと、抽象メソッドのコンストラクタを記述することができます。 コンストラクタを書くときは、基本クラスからアクセスするだけです。

基本クラスのコンストラクタ:

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

派生/コンクリート/サブクラスのコンストラクタ:

public SubClass() : base() { }

ここでのポイントは、基本クラスから描画されたインスタンス変数がベースフィールド名を埋め込む可能性があることです。 「this」を使用して現在のインスタンス化されたオブジェクト値を設定します。 現在のインスタンスと、それをインスタンス化している必要な権限レベル(アクセス修飾子)に関してオブジェクトを正しく形成することができます。


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

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

public Class ClassName{
    public int PropName{get;set;}
    public ClassName{
        PropName=0;  //Default Value
    }
}




automatic-properties