2009-06-12 4 views
3

설명을 돕기 위해이 예제를 작성했습니다. 보시다시피 개체 계층이 있습니다. GetFeatures() 함수를 수정하여 인스턴스화 된 객체 유형의 생성자가 추가 한 기능 만 반환하고 싶습니다. 예를 들어 BasicModel.GetFeatures (새 LuxuryModel())는 "Leather Seats"및 "Sunroof"기능 만 반환해야합니다. 내가해야한다면 반사 사용에 신경 쓰지 않아도됩니다.생성 된 하위 클래스의 유형을 기반으로 기본 클래스의 객체 컬렉션을 필터링하는 방법은 무엇입니까?

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 

답변

1

기본 계층의 인스턴스를 만들고 기본 클래스의 기능을 파생 클래스의 기능에서 뺍니다.

또는 클래스 계층 구조를 조금만 변경하면 더 쉽게 사용할 수 있습니다.

예를 들어, Feature 속성을 ModelFeatures 및 AllFeatures라는 두 속성으로 나눌 수 있습니다.

ModelFeatures는 현재 모델에만 해당됩니다 (LuxuryModel의 경우 "가죽 시트"및 "Sunroof"등). AllFeatures는 MyBase.AllFeatures 및 ModelFeatures의 합집합을 반환합니다. 이렇게하면 현재 모델의 기능을 사소한 속성에 액세스 할 수 있습니다.

P. 내 VB 오류를 용서해주십시오, C#은 내가 선호하는 언어입니다.

public IList<Function> GetFeatures(BasicModel model) 
{ 
    return model.Features.Where(f => f.Model.GetType() == model.GetType()).ToList(); 
} 
1

작업을해야하는 C#을 구문입니다 이것이 당신의 자동차 Heirachy에 속한다고 생각합니다. 정적 데이터를 얻고 기본 클래스를 컨테이너의 형태로 사용하여 decendant 유형을 키로 사용하려고합니다. 당신이 볼 수 있듯이, 이것은 간단하고 무언가 간단한 코딩을 다소 어색하고 지나치게 복잡하게 만든다.

필자는 정적 데이터를 속하는 위치 (이 경우)에서 Feature 클래스 자체를 사용하는 경향이 있습니다. 나는 VB 녀석이 아니기 때문에 C#에서이 코드 스 니펫을 사용한다. 그래서 기능 클래스 자체에

정적 특성 (또는 방법)

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

이 그리고 다른 모델 반복합니다. 이제 정적 데이터 용 컨테이너가 클래스 자체에 있습니다.

+1

VB에서는 필터링되지 않습니다. 모든 기능이 여전히 반환됩니다. – adam0101

+1

VB 또는 C#으로 처리되었는지 여부는 중요하지 않습니다. 이와 같이 Where 절을 사용하고 유형이 실제로 다르면 (GetType을 사용하면 두 인스턴스의 기본 유형을 비교하지 않고 각 인스턴스의 정확한 유형 만 비교할 수 있음), 필터링 된 목록을 가져와야합니다. "작동하지 않는"경우 유일한 옵션은 주어진 모델의 모든 기능이 전달하는 모델을위한 것입니다. – jrista

1

(위의 샘플 코드 기준)

정직 그렇게하지 말해서 : 나는, 그래서 여기 VB.NET 구문 실제 익숙하지 오전

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(); 
} 
1

이 데이터가 (내 다른 대답을 참조) 정적하지 않으려면이 작업을 수행하는 또 다른 방법, 그리고 당신을 위해 wnat 확장 할 수 새 클래스로, 해당 클래스가 기능 세트를 제어하도록합니다.그런 다음 다형성을 사용하십시오 (VB 사용자가 아니기 때문에 다시 C#을 사용하십시오).

기본 클래스에서 상급 클래스에서 특성을 재정의하는 가상 메서드를 만듭니다. 다형성은 변수를 기본 모델로 사용할 수있게합니다. 올바른 목록을 반환하는 자손 유형으로 생성됩니다.

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