문제

C#의 제네릭에 대해 이해 한 내용을 확인하고 싶습니다. 이것은 제가 일반 기본 클래스가 유형-안전 파생 인스턴스를 만드는 데 사용되는 몇 가지 코드베이스에서 나타났습니다. 내가 말하는 것에 대한 아주 간단한 예,

public class SomeClass<T>
{
    public virtual void SomeMethod(){ }
}

public class DeriveFrom :SomeClass<string>
{
    public override void SomeMethod()
    {
        base.SomeMethod();
    }
}

파생 된 인스턴스를 다형성 방식으로 사용하고 싶을 때 문제가 발생합니다.

public class ClientCode
{
    public void DoSomethingClienty()
    {
        Factory factory = new Factory();
        //Doesn't compile because SomeClass needs a type parameter!
        SomeClass someInstance = factory.Create();

        someInstance.SomeMethod();
    }
}

일단 상속 계층 또는 인터페이스에 제네릭을 소개하면 더 이상 해당 클래스 제품군을 그 자체를 제외하고 다형성 방식으로 사용할 수없는 것 같습니다. 그게 사실인가요?

도움이 되었습니까?

해결책

내가 볼 수있는 한, 코드를 소비하면 일반 클래스의 세부 사항이 필요하지 않습니다 (즉, 무엇에 의존하지 않습니다. T 이다). 따라서 인터페이스를 소개하지 않겠습니까? SomeClass<T> 이 인터페이스의 인스턴스를 구현하고 사용합니다.

예 :

public interface ISome
{
    void SomeMethod();
}

public class SomeClass<T>: ISome
{
    public virtual void SomeMethod(){ }
}

public void DoSomethingClienty()
{
    Factory factory = new Factory();
    ISome someInstance = factory.Create();

    someInstance.SomeMethod();
}

이제 서브 클래스 SomeClass<T> 다르게 작동 할 수 있습니다 TS이지만 코드 소비는 변경되지 않습니다.

다른 팁

나는 당신이 제네릭의 요점을 오해하고 있다고 생각합니다. 제네릭을 사용하면 유형이 필요한 클래스를 일반화 할 수 있지만 특히 어떤 유형이든 상관하지 않습니다. 예를 들어, a List<string> 문자열 목록이지만 무엇을 List 이다? 아무것도없는 목록을 갖는 것은 다소 쓸모없는 개념입니다.

각 전문 수업 (즉, List<string>) 이다 고유 한 유형입니다, 그리고 컴파일러는이를 그렇게 취급합니다. 그것은이다 가능한 일반 유형 자체에 도달하려면 (typeof(List<>) 예를 들어), 그러나 대부분의 경우에는 쓸모가 없으며, 확실히 인스턴스를 만들 수는 없습니다.

나는 모든 일반 유형의 기본 역할을하기 위해 추상 클래스를 사용하는 것을 선호합니다.

public abstract class SomeClass 
{
    public abstract void SomeMethod();
}

public class SomeClass<T> : SomeClass
{
    public override void SomeMethod() { }            
}

public class DeriveFrom<String> : SomeClass<String>
{
    public override void SomeMethod() { base.SomeMethod(); }            
}

상속 계층 또는 인터페이스에 제네릭을 소개하면 더 이상 해당 클래스 제품군을 다형성 방식으로 사용할 수없는 것 같습니다.

맞습니다.이 상황과 매우 유사합니다.

class StringContainer
{
}

class IntContainer
{
}

StringContainer container = new IntContainer(); // fails to compile

그러나 당신은 이것을 할 수 있습니다 :

class Container
{
}

class Container<T> : Container
{
}

Container container = new Container<String>(); // OK

당신이 찾고있는 것은 다음과 같습니다.

  SomeClass(of someType) someInstance = factory(of someType).Create();
or maybe
  SomeClass(of someType) someInstance = factory.Create(of someType)();
or
  SomeClass(of someType) someInstance = factory.Create();

다른 일반 클래스를 생성하기위한 공장 클래스 세트를 가질 수 있거나 일반 유형 매개 변수가있는 공장을 가질 수 있습니다. 일반적인 클래스 자체가 아니라 클래스. 하나의 특정 형태의 일반 유형의 인스턴스를 반환하도록 설계된 공장을 가질 수도 있습니다.

public Class ReflectionReport<T> 
{
    // This class uses Reflection to produce column-based grids for reporting.  
    // However, you need a type in order to know what the columns are. 
}

... so, in another class you have...

public Class ReflectionReportProject {
    ReflectionReport<Thang> thangReport = new ReflectionReport<Thang>(); 
    ReflectionReport<Thong> thongReport = new ReflectionReport<Thong>(); 



    ... some more stuff ...

    // Now, you want to pass off all of the reports to be processed at one time....
    public ReflectionReport<????>[] ProvideReports() 
    {
        return new ReflectionReport<????>[] { thangReport, thongReport } ;
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top