2012-03-16 7 views
1

여기에 OO 문제가 있습니다. 공통 속성과 특정 속성을 가진 두 개의 세션이 있습니다. 기본 클래스를 만들고 모든 공통 속성/메서드를 캡슐화했습니다. 두 개의 세션에는 Ranges라는 공통 유형이 있으며, 세션에는 공통 속성과 특정 속성이 있습니다. 그래서 나는이 경우에 슈퍼 타입으로 프로그램하고 런타임에 인스턴스를 만들 수 있다고 생각했다.C에서 슈퍼 유형 프로그래밍 #

public class Level 
{ 
    private readonly Ranges _range; 

    public Level(Ranges range) 
    { 
     _range = range; 
    } 

    public Ranges Range 
    { 
     get { return _range; } 
    } 

    public void CommonMethod() 
    { 
     throw new NotImplementedException(); 
    } 

    public int CommonProperty; 
} 

public class ALevel : Level 
{ 
    public ALevel() 
     : base(new ARange()) 
    { 

    } 

    public int ALevelProperty; 
} 

public class BLevel : Level 
{ 
    public BLevel() 
     : base(new BRange()) 
    { 

    } 

    public int BLevelProperty; 
} 

public class Ranges 
{ 
    public int CommonRangeProperty; 
} 

public class ARange : Ranges 
{ 
    public int ARangeProperty; 

    public ARange() 
    { 

    } 
} 

public class BRange : Ranges 
{ 
    public int BRangeProperty; 
} 

public class ASession 
{ 
    public ASession() 
    { 
     Level = new ALevel(); 
    } 

    public ALevel Level { get; set; } 
} 

public class BSession 
{ 
    public BSession() 
    { 
     Level = new BLevel(); 
    } 

    public BLevel Level { get; set; } 
} 

세션 개체를 만들 때 특정 세션 범위 속성을 포함하지 않습니다. 기본 클래스의 속성에만 액세스 할 수 있습니다. aSession.Level.Range.CommonRangeProperty = 1; aSession의 특정 속성 aSession.Level.Range.ARangeProperty에 액세스 할 수 없습니다.

여기에 뭔가 잘못입니까?

public class Test 
{ 
    public static void Main(string[] args) 
    { 
     ASession aSession = new ASession(); 

     aSession.Level.Range.CommonRangeProperty = 1; 
     //Not able to see ARangeProperty 

    } 
} 

답변

3

꽤 간단합니다 Ranges-Range의 종류 (안 특정 ARangeBRange)을 설정 Level

클래스.

public abstract class Level<TRange> 
    where TRange : Ranges 
{ 
    private readonly TRange _range; 
    protected Level(TRange range) 
    { 
     this._range = range; 
    } 
    public TRange Range 
    { 
     get 
     { 
      return this._range; 
     } 
    } 
} 

public class ALevel : Level<ARange> 
{ 
    public ALevel() 
     : base (new ARange()) 
    { 
    } 
} 

하면 더욱이 예제를 수행 할 수 있습니다 : 당신은 예를 들어, 제네릭으로 작동합니다

public abstract class Level<TRange> 
    where TRange : Ranges/*, new()*/ // i'm not sure about the new() ... have no compiler access right now to check! 
{ 
    private readonly TRange _range = new TRange(); 
    public TRange Range 
    { 
     get 
     { 
      return this._range; 
     } 
    } 
} 

public class ALevel : Level<ARange> 
{ 
} 

우리의 당신과 같이, ALevel에 다른 회원을 소개 할 수 :

public class ALevel : Level 
{ 
    public ARange ARange; 
} 

RangeLevel 가상으로 지정하고 오버라이드 Range (redirec t를 콘크리트 ARange 또는 BRange)로 변경합니다. 무겁게 이후 사용에 따라

은 ... 당신은 당신이 당신의 일반적인에서 재정의 할 수 있습니다베이스 부재를 소개합니다 (제네릭 제약없이) 다른 기본 클래스를 소개한다 RangeRanges로을 속성에 일반 액세스를 필요로하는 경우 기본 클래스. 그래서 당신은 내가 정확하게 문제를 이해한다면 ...

+0

와우! Ur 솔루션은 간단하면서도 강력했습니다. 고맙습니다! 하지만 코드 문제를 설명해 주시겠습니까? – sundar

+0

@sundar 첫 번째 문장에서 "학급 수준이 범위의 범위를 설정합니다 (특정 ARange 또는 BRange가 아닙니다)"-이 시점이 명확한 지 설명하려고했습니다. –

+0

하지만 Ranges는 여기에서 수퍼 유형이므로 파생 유형을 할당 할 수 있어야합니다. – sundar

1

당신이 제네릭을 사용할 필요 (기본 클래스/O를 사용하면 콘크리트 TRange의 지식 Level<TRange> 캐스팅해야 승) LevelALevel의 인스턴스를 캐스팅 할 수 있습니다 당신이 성취하려는 일을하는 것. 코드는

public class Level<TRange> 
    where TRange: Ranges 
{ 
    private readonly TRange _range; 

    public TRange Range 
    { 
     get 
     { 
      return this._range; 
     } 
    } 
} 

public class ALevel : Level<ARange> 
{ 

} 

과 같습니다. 그러면 수퍼 클래스는 Range를 기본 유형으로 사용할 수 있으며 파생 클래스는이를 특정 유형으로 사용할 수 있습니다.

+0

'등급'은 '비공개'가시성으로 인해 'Level._range'에 액세스 할 수 없습니다. 당신은 적어도'_range'를 protected로 표시해야합니다 - 또는 protected protected get-property를 도입해야합니다 –

+0

@AndreasNiedermair 좋은 캐치 ... 고정 – Yaur

+0

당신을 환영합니다! –