23

私はC#に非常に慣れていないので、ご容赦ください...

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

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

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

IsSomethingtoTrueSomeListtoの両方のデータ メンバーを初期化したいと思いますnew List<string>()。通常はコンストラクターで行いますが、これは部分クラスであるため、コンストラクターには触れたくありません (すべきでしょうか?)。

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

ありがとう

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

4

8 に答える 8

41

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番目の提案は、この状況で機能します。

于 2009-08-13T15:15:46.720 に答える
9

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

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

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

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

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

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

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

于 2009-08-13T15:15:42.400 に答える
6

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

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

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

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

于 2009-08-13T15:17:01.383 に答える
5

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

}

もう1つのアプローチは、プロパティを「遅延ロード」することですが、このアプローチはそれほどエレガントではありません。

    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");
        }
    }
于 2010-12-01T03:09:15.843 に答える
4

これには、自動プロパティを使用せず、古い方法を使用します

YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
   get{return _yourParameter;}
   set{_yourParameter=value;}
}
于 2009-08-13T15:20:11.160 に答える
3

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

public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();
于 2016-03-16T14:37:17.097 に答える
1

両方のプロパティには、必要なデフォルト値がすでに含まれています。

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

于 2009-08-13T15:16:40.557 に答える