2010-01-06 4 views
2

제네릭 형식 매개 변수를 인터페이스로 사용해야하지만 제네릭 클래스 (SomeGenericType)의 형식을 다음과 같이 인스턴스화하고 싶습니다.new() 제약 조건을 가진 제네릭 형식 매개 변수 인 추상 형식 및 인터페이스 관련 문제

class Program 
{ 
    static void Main(string[] args) 
    { 
     var val = new SomeGenericType<ISomeInterface>(); 

     Console.ReadKey(); 
    } 
} 

internal class SomeGenericType<T> where T : new() 
{ 
    public SomeGenericType() 
    { 
     var test = new T(); 
    } 
} 

public class SomeClass : ISomeInterface 
{ 
    public string TestVal { get; set; } 
} 

public interface ISomeInterface 
{ 
    string TestVal { get; set; } 
} 

이 다음과 같은 컴파일 타임 오류가 발생합니다 :

"ISomeInterface는 제네릭 형식 또는 메서드 SomeGenericType에 매개 변수로 'T'를 사용하기 위해 공공 매개 변수가없는 생성자가 아닌 추상 형식이어야합니다"

왜 이런 일이 벌어지는 지 이해하지만,이 문제를 해결할 방법이 있는지 궁금합니다.

감사합니다.

+0

제약 조건을 추가하면 도움이 될까요? '어디 T : ISomeInterface, new()'. 앞서 언급했듯이 generic에 대한 구체적인 구현을 제공해야 할 것입니다. new() 제약을 보장 할 다른 방법이 없기 때문입니다. – Sapph

+1

Interface1, Class1 : Interface1, Class2 : Interface1이있는 경우 Class1 또는 Class2의 인스턴스를 만들려면 컴파일러에서 어떻게 추측해야합니까? –

답변

1

컴파일러가 주어진 인터페이스에 대해 인스턴스화 할 클래스를 알 수있는 방법이 없습니다. David M은 다음과 같이 지적합니다 :

나는이 간단한 요구 사항 때문에 프레임 워크를 사용하는 것이 좋다고 생각합니다. 당신이 할 수있는 것은이 같은 자신의 Factory 클래스를 만드는 것입니다 : 몇 정신 검사에서

public class Factory 
{ 
    Dictionary<Type, Type> typeMapping = new Dictionary<Type, Type>(); 

    public void Register<IType, CType>() 
    { 
    typeMapping.Add(typeof(IType),typeof(CType)); 
    } 

    public IType Create<IType>() 
    { 
    Activator.CreateInstance(typeMapping[typeof(IType)]); 
    } 
} 

던져이 클래스를 사용할 준비가되어 있어야합니다.

6

아니는 new() 제약은 유형의 인스턴스가 명확

new T() 

이 abstract 클래스 나 인터페이스, 만 구체적인 클래스 중 하나의 사실이 아니다 구문으로 생성 할 수 있어야 공개 매개 변수없는 생성자.

당신은 제약 조건을 제거하고 사용하여 런타임 때까지 문제를 연기 할 수있다 :

Activator.CreateInstance<T>() 

대신 개체를 만들 수 있습니다. 그런 다음 런타임에서 사용되는 실제 유형이 이러한 제약 조건을 충족시키는 한 원하는대로 코드가 작동합니다. 그러나 인터페이스 또는 추상 클래스를 사용하려고하면 런타임 오류가 발생합니다. 특정 경우

,이 라인은 당신은 컴파일 타임 오류가 지나서 예외

var val = Activator.CreateInstance<SomeGenericType<ISomeInterface>>(); 

를 던져,하지만 효과 것입니다.

1

여기에는 new 제약이 콘크리트 유형 구현과 관련되어 있습니다. 이것은 직접적으로 인스턴스화 될 수 없으므로 단순한 인터페이스 나 추상 클래스에서는 작동하지 않습니다. 당신이 ISomeInterface을 요청하고 "기본"구현 SomeClass의 인스턴스를 가질 수있는 방법을 찾고있는 것처럼 당신은 관련성이없는 여기

var val = new SomeGenericType<SomeClass>() 
2

또 다른 아이디어를 구체적인 클래스를 제공해야하지만, 그것은 본다 제공됩니다. 이것은 Inversion of Control (IOC) 컨테이너가 처리 할 수있는 일종의 것입니다. 더 자세히 조사하려면 Spring.NET, Microsoft Unity, AutoFac, LinFu 또는 다른 많은 프레임 워크 중 하나를 살펴보십시오.

관련 문제