3

説明を助けるためにこの例を書きました。ご覧のとおり、オブジェクト階層があります。GetFeatures() 関数を変更して、インスタンス化したオブジェクト タイプのコンストラクターによって追加された機能のみを返すようにしたいと考えています。たとえば、BasicModel.GetFeatures(new LuxuryModel()) は、機能「レザー シート」と「サンルーフ」のみを返す必要があります。必要に応じてリフレクションを使用してもかまいません。

Public Class Feature

    Public Sub New(ByVal model As BasicModel, ByVal description As String)
        _model = model
        _description = description
    End Sub

    Private _model As BasicModel
    Public Property Model() As BasicModel
        Get
            Return _model
        End Get
        Set(ByVal value As BasicModel)
            _model = value
        End Set
    End Property

    Private _description As String
    Public Property Description() As String
        Get
            Return _description
        End Get
        Set(ByVal value As String)
            _description = value
        End Set
    End Property

End Class


Public Class BasicModel
    Public Sub New()
        _features = New List(Of Feature)
    End Sub

    Private _features As List(Of Feature)

    Public ReadOnly Property Features() As List(Of Feature)
        Get
            Return _features
        End Get
    End Property

    Public Shared Function GetFeatures(ByVal model As BasicModel) As List(Of Feature)
        'I know this is wrong, but something like this...'
        Return model.Features.FindAll(Function(f) f.Model.GetType() Is model.GetType())
    End Function
End Class


Public Class SedanModel
    Inherits BasicModel

    Public Sub New()
        MyBase.New()
        Features.Add(New Feature(Me, "Fuzzy Dice"))
        Features.Add(New Feature(Me, "Tree Air Freshener"))
    End Sub
End Class


Public Class LuxuryModel
    Inherits SedanModel

    Public Sub New()
        MyBase.New()
        Features.Add(New Feature(Me, "Leather Seats"))
        Features.Add(New Feature(Me, "Sunroof"))
    End Sub
End Class
4

5 に答える 5

1

If you want to keep your current hierarchy/properties, just create an instance of the base class and subtract the Features in the base class from the features in the derived class.

Alternatively, you might want to consider changing your class hierarchy a bit to make this easier on yourself.

For instance, you could split the Features property into two properties, say ModelFeatures and AllFeatures.

ModelFeatures is specific to the current model ("Leather Seats" and "Sunroof" for LuxuryModel, etc.) AllFeatures returns the union of MyBase.AllFeatures and ModelFeatures. This makes getting the current Model's features a trivial property access.

P.S. Please forgive my VB errors, C# is my preferred lang.

于 2009-06-12T23:12:10.467 に答える
1

I am not real familiar with VB.NET syntax, so here is C# syntax that should work:

public IList<Function> GetFeatures(BasicModel model)
{
    return model.Features.Where(f => f.Model.GetType() == model.GetType()).ToList();
}
于 2009-06-12T23:16:03.873 に答える
1

(上記のサンプルコードに基づく)

正直なところ、これはあなたの Car Heirachy に属しているとは思いません。静的データを取得し、基本クラスをそのコンテナーとして使用し、派生型をキーとして使用しているようです。ご覧のとおり、これにより、単純なものが不器用または過度に複雑なコーディングになります。

私は、静的データをそれが属する場所 (この場合) に、Feature クラス自体に配置する傾向があります。私は VB の専門家ではないので、このコード スニペットは C# です。

したがって、Feature クラス自体に、静的プロパティ (またはメソッド)があります。

public static IEnumerable<Feature> GetLuxuryFeatureSets
{
  get
  {
    yield return new Feature() { Name = "Leather Seats" };
    yield return new Feature() { Name = "Sunroof" };
  }
}

他のモデルについても繰り返します。これで、意味のある静的データのコンテナであるクラス自体ができました。

于 2009-06-12T23:38:01.480 に答える
1

ある機能を別の機能と区別する方法がないため、モデルに追加された機能を尋ねることができる必要があります。コンストラクターのリストに機能を追加するのではなく、特定のモデルが追加する機能のリストを返すメソッドが必要です...

public class LuxuryModel
{
  public LuxuryModel
  {
     Features.Add( GetFeatures() );
  }
  public List<Features> GetFeatures()
  {
     return new List<Features>( /* new up leather and whatever */
  }
}

次に、GetFeatures はダウンキャストを実行し、指定されたインスタンスに、その特定のインスタンスが追加する機能のリストを要求できます...

public List<Features> GetFeatures<T>( BasicModel model )
{
   var m = Model as T;
   return m.GetFeatures();
}
于 2009-06-12T23:39:01.977 に答える
1

このデータを静的にしたくない場合(私の他の回答を参照)、新しいクラスに拡張可能にし、それらのクラスが機能セットを制御できるようにする別の方法。次に、ポリモーフィズムを使用します (ここでも C# です。私は VB の専門家ではありません)。

基本クラスで機能を返す仮想メソッドを作成し、派生クラスでプロパティをオーバーライドします。ポリモーフィズムにより、変数が子孫型として構築されている限り、変数を basicmodel 型として使用して正しいリストを返すことができます。

  public class BasicModel
  {
    public virtual IEnumerable<Feature> GetFeatures 
    {
      get
      {
        throw new NotImplementedException();
      }
    }
  }


  public class LuxuryModel :BasicModel
  {
    public override IEnumerable<Feature> GetFeatures
    {
      get
      {
        yield return new Feature() { Name = "Leather Seats" };
        yield return new Feature() { Name = "Sunroof" };
      }
    }
  }



private void button1_Click(object sender, EventArgs e)
{
  StringBuilder sb = new StringBuilder();

  BasicModel bm = new LuxuryModel();

  foreach (Feature f in bm.GetFeatures)
  {
    sb.AppendLine(f.Name);
  }
  MessageBox.Show(sb.ToString());
}
于 2009-06-12T23:54:39.677 に答える