3

C# では、基本クラスのコンストラクターは常に継承されたクラスのコンストラクターの前に呼び出されることが知られています。そのために問題に直面しており、それを回避する方法が見つかりません。

基底クラスを持つ

public class BaseClass 
{
  public IValuesProvider ValuesProvider {get; protected set; }
  public virtual IList<Value> Values 
  {
      get {return ValuesProvider.GetAll(); }
  }
  public BaseClass(IValuesProvider valuesProvider)
  {
       ValuesProvider = valuesProvider;
       Load();
  }

  public virtual void Load()
  {
     foreach (var value in Values)
     {
       // DO something with value
     }
  } 

}

および継承されたクラス

public class InheritedClass : BaseClass
{

  public int? Filter {get; protected set;}

  public override IList<Value> Values 
  {
      get {return base.Values.Where(v => v.Id > Filter); }
  }

  public InheritedClass (IValuesProvider valuesProvider, int filter)
     : base (valuesProvider)
  {
      Filter = filter;
  }     
}

InheritedClass をインスタンス化すると、Values を返そうとすると Filter で Null 参照例外が発生します。したがって、「フィルター」が割り当てられているときに Load() を1回だけ実行する必要があります。InheritedClass も次のように継承できるという制約を追加します。

 public class InheritedClass2 : InheritedClass
{

  public int? Filter2 {get; protected set;}

  public override IList<Value> Values 
  {
      get {return base.Values.Where(v => v.Id > Filter2); }
  }

  public InheritedClass2 (IValuesProvider valuesProvider, int filter1, int filter 2)
     : base (valuesProvider, filter1)
  {
      Filter2 = filter2;
  }     
}

汚いコードを書かずに Load を効率的に呼び出すにはどうすればよいですか?

4

4 に答える 4

0

遅延読み込みがここに行く方法だと思います。

プロパティを追加できます

private bool loaded;

基本クラスにメソッドを追加します

protected void EnsureLoaded() {
  if (!loaded) Load();
}

Load() は、AllValues などのすべての値を保持するリストに値をロードした後、loaded を true に設定する必要があります。

継承されたクラスでは、次のことを行います。

public override IList<Value> Values 
  {
      get {
        EnsureLoaded();
        return base.AllValues.Where(v => v.Id > Filter); 
      }
  } 

次に、値をロードする必要があるときはいつでも、EnsureLoaded を呼び出します。

于 2013-08-01T12:13:42.783 に答える