0

私はクラスを持っています:

public class TaskDiplayModel
{
    public int taskId { get; set; }

    [DisplayName("Task Description")]
    public string description { get; set; }

    [DisplayName("Priority")]
    public string priority { get; set; }

    [DisplayName("State")]
    public string state { get; set; }

    [DisplayName("Due By")]
    public DateTime deadline { get; set; }

    [DisplayName("Created By")]
    public PersonObject created_by { get; set; }

    [DisplayName("Assigned To")]
    public PersonObject assigned_to { get; set; }

    [DisplayName("Category")]
    public string category { get; set; }

    [DisplayName("Sub Category")]
    public string subCategory { get; set; }

    [DisplayName("Created")]
    public DateTime createdDate { get; set; }

    [DisplayName("Updated")]
    public DateTime lastUpdatedDate { get; set; }

    [DisplayName("Updated By")]
    public PersonObject lastUpdatedBy { get; set; }    
}

次に、このクラスから継承する別のクラスがあります。

public class TaskModifyModel : TaskDiplayModel
{
    public int priorityId { get; set; }
    public int stateId { get; set; }
    public int categoryId { get; set; }
    public int subCategoryId { get; set; }

    public SelectList states { get; private set; }
    public SelectList priorities { get; private set; }
    public SelectList categories { get; private set; }
    public SelectList subCategories { get; private set; }

    public TaskModifyModel()
    {
        SetupReferenceData(0);
    }

    public TaskModifyModel(int taskId)
    {

        var taskService = new TaskService();
        var task = taskService.GetTask(taskId);
    }
}

私のアプリケーションでは、TaskModifyModelオブジェクトを作成します。ただし、基本クラスの文字列フィールドはnullです。私はそれらが作成され、であると期待していますString.Empty。しかし、それらにアクセスしようとすると例外が発生します。私は何かが足りないのですか?

ちなみに、これらはMVC3モデルです。質問とは無関係だと思うので、クラスのコードは省略されています。

4

2 に答える 2

8

.NETでは、文字列のデフォルト値はnullではなくString.Empty、であるため、プロパティの値を特にに設定しない限り、プロパティは。のString.Emptyままになりますnull

文字列プロパティをデフォルトでnullではなく空の文字列にしたい場合は、通常、コンストラクターで設定することによってこれを行います。

public void TaskDiplayModel()
{
    description = String.Empty;
    priority = String.Empty;
    state = String.Empty;
}

または、autoプロパティの代わりにfield-backedプロパティを使用し、バッキングフィールドを設定します。

private string _description = String.Empty;

[DisplayName("Task Description")]
public string description
{
    get { return _description; }
    set { _description = value; }
}

個人的には、コーディングが少ないため、通常はコンストラクターで最初のオプションを使用します。

于 2012-08-25T11:42:07.657 に答える
1

次の要約版を考えると、rally25rsの優れた回答(とにかく私から+1)に追加するだけです。

public class TaskDiplayModel
{
    private string _priority = string.Empty;
    public int TaskId { get; set; }
    public string Description { get; set; }
    public string Priority
    {
       get { return _priority; }
       set { _priority = value; }
    }
    public TaskDisplayMode()
    {
      Description = string.Empty;
    }
}
public class TaskModifyModel : TaskDisplayMode
{
  public int PriorityId { get; set; }
  public TaskModifyModel()
    :base()
  {
    PriorityId = 3;
  }
}

その場合、構築時の順序TaskModifyModelは次のとおりです。

  1. 、to 、to 、およびtoに設定_priorityします(値が指定されていない場合、すべてが参照の場合、数値の場合、および構造体のフィールドがとでいっぱいになるように設定されます)。string.EmptyTaskId0PriorityId0Descriptionnullnull00null
  2. のコンストラクタ本体をTaskDiplayModel実行する場合は、に設定Descriptionstring.Emptyます。
  3. のコンストラクター本体TaskModifyModelが実行され、に設定PriorityIdされ3ます。

ネストされた継承がより複雑な場合など。原則として、これの一部は最適化されることが期待できるため、値の設定方法に関して別のアプローチを採用する方が速いか遅いかを心配する必要はありません。デバッグの実行を除いて、そうはなりません。ただし、コンストラクター内で仮想メソッドを呼び出さないようにするルールについては説明しています。ほとんどの場合、上記の順序を気にする必要はなく、コンストラクターを単一のユニットとして扱うだけで、完全に構築されたオブジェクトが作成されます。仮想呼び出しで遊び始めると、ある時点PriorityIdではが0、別の時点ではがであるため、上記の順序が非常に重要になり3ます。

于 2012-08-25T14:51:52.010 に答える