web-dev-qa-db-ja.com

C#:部分クラスのプロパティのデフォルト値を設定するにはどうすればよいですか?

私はC#に非常に慣れていないので、我慢してください...

私は部分クラスを実装しています。次のように2つのプロパティを追加したいと思います。

_public partial class SomeModel
{
    public bool IsSomething { get; set; }
    public List<string> SomeList { get; set; }

    ... Additional methods using the above data members ...
}
_

IsSomethingからTrueおよびSomeListからnew List<string>()の両方のデータメンバーを初期化したいと思います。通常はコンストラクターで行いますが、これはコンストラクターに触れたくない部分クラスであるためです(そうすべきですか?)。

これを達成するための最良の方法は何ですか?

ありがとう

PS私はASP.NET MVCで作業しており、特定のモデルに機能を追加しているため、部分クラスです。

20
Roee Adler

C#6用に更新

C#6では、自動プロパティにデフォルト値を割り当てる機能が追加されました。値は任意の式にすることができます(定数である必要はありません)。ここにいくつかの例があります:

// Initialize to a string literal
public string SomeProperty {get;set;} = "This is the default value";

// Initialize with a simple expression
public DateTime ConstructedAt {get;} = DateTime.Now;

// Initialize with a conditional expression
public bool IsFoo { get; } = SomeClass.SomeProperty ? true : false;

元の回答

自動的に実装されるプロパティは、クラスコンストラクターで初期化できますが、プロパティ自体では初期化できません。

public SomeModel
{
    IsSomething = false;
    SomeList = new List<string>();
}

...またはフィールドに裏付けされたプロパティを使用して(少し作業が増える)、フィールド自体を初期化できます...

private bool _IsSomething = false;
public bool IsSomething
{
    get { return _IsSomething; }
    set { _IsSomething = value; }
}

更新:私の上記の答えは、これが部分クラスにあるという問題を明確にしていません。 Mehrdadの答え は、部分的な方法を使用するソリューションを提供します。これは、私の最初の提案と一致しています。自動的に実装されないプロパティ(手動で実装されるプロパティ?)を使用するという私の2番目の提案は、この状況で機能します。

37
STW

最初のプロパティ(IsSomething)はブール値です。デフォルトではfalseになります。

2番目のプロパティは参照型なので、デフォルトではnullに設定されており、ユーザーの操作は必要ありません。参照型(クラス)は.NETでは自動的にnullとして開始されるため、コンストラクターを操作する必要はありません。

デフォルト以外の値を使用したい場合は、2つのオプションがあります-

まず、バッキングストレージフィールドを使用します。

private bool isSomething = true;
public bool IsSomething {
    get { return this.isSomething; }
    set { this.isSomething = value; }
}

2番目のオプション-コンストラクターに追加します。

最初のオプションには余分なオーバーヘッドがないことに注意してください。これは基本的に、自動プロパティを使用するときにコンパイラーが行うことです。

8
Reed Copsey

部分クラスの2つの部分に2つのコンストラクターを含めることはできません。ただし、 partial methods を使用して、次のようなことを行うことができます。

// file1:
partial void Initialize();
public Constructor() {
    // ... stuff ... initialize part 1
    Initialize();
}

// file2:
void Initalize() {
    // ... further initializations part 2 might want to do
}

部分クラスのどの部分も部分メソッドを定義していない場合、それに対するすべての呼び出しは省略されます。

5
Mehrdad Afshari

WCF部分クラスのユーザーに対する警告

(サービス参照の追加によって生成された)WCFプロキシクラスにプロパティを追加しようとしている場合、 明らかにコンストラクターがないため、プライベートフィールドが初期化されていないことに驚くかもしれません と呼ばれます。

(他のいくつかの回答で示唆されているように)これを行おうとすると、呼び出されません:

    private bool _sendEmail = true;

これは、フィールドが部分クラスにあるかどうかとは関係ありません。

あなたがしなければならないことは、オブジェクトへのさらなる初期化を可能にする [OnDeserialized] 属性を追加することです。これはSystem.Runtime.Serializationの一部なので、 DataContractSerializer を使用する場合のシリアル化のコンテキストでのみ役立ちます。

public partial class EndOfDayPackageInfo
{
    [OnDeserialized()]
    public void Init(StreamingContext context)
    {
        _sendEmail = true;
    }

    private bool _sendEmail;
    public bool SendEmail
    {
        get
        {
            return _sendEmail;
        }
        set
        {
            _sendEmail = value;
            RaisePropertyChanged("SendEmail");
        }
    }

}

別のアプローチは、プロパティを「遅延ロード」することですが、このアプローチはあまりエレガントではありません。

    private bool _sendEmail;
    private bool _sendEmailInitialized;

    public bool SendEmail
    {
        get
        {
            if (!_sendEmailInitialized)
            {
                _sendEmailInitialized = true;
                _sendEmail = true;  // default value
            }

            return _sendEmail;
        }
        set
        {
            if (!_sendEmailInitialized)
            {
                // prevent unwanted initialization if 'set' is called before 'get'
                _sendEmailInitialized = true;
            }

            _sendEmail = value;
            RaisePropertyChanged("SendEmail");
        }
    }
5
Simon_Weaver

これには、自動プロパティを使用しないでください、古い方法

YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
   get{return _yourParameter;}
   set{_yourParameter=value;}
}
4
Gregoire

C#バージョン6.0のユーザーは、次のようにプロパティを初期化できます。

public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();
3
Ant

どちらのプロパティにも、必要なデフォルト値がすでにあります。

部分クラスにコンストラクタがあることには何の問題もありません。ソースコードが複数のファイル/宣言に分散しているという事実を除けば、部分クラスは決して特別なものではありません。

1
Paul Turner
 private bool _InternalUserContactUpdate = false;
        public bool InternalUserContactUpdate
        {
            get { return _InternalUserContactUpdate; }
            set { _InternalUserContactUpdate = value; }
        }

次に、条件の値をオーバーライドする場合、

if(!objUserModel.FirstName.ToLower().Equals(entry.Key[0].Attributes.Contains("firstname").ToString().ToLower()))
        {
             objUserModel.InternalUserContactUpdate= true;
        }

これが役に立てば幸い

0
Subhamay