공장에서 실험을하면서 컴파일 오류가 발생했습니다. 실제 코드에서는 DI 시스템을 사용하기 때문에 실제로 사용할 팩토리 구현은 아닙니다. 나는 이것이 내가 도움을 구하지 않는 것이기 때문에 이것을 앞에서 언급하고 싶었다.오류 : "유형을 제네릭 유형의 메소드에서 유형 매개 변수로 사용할 수 없습니다." 제약이나 주조로 해결할 수 있습니까?
아래 스 니펫과 혼동 스럽다면 여러 유형을 반환 할 수 있도록 Create() 메소드를 제한하는 방법이 있습니다. 컴파일러 오류는 다음과 같습니다
public static class UniversalFactory
{
// New factories should be added here.
private static readonly IFactory<IFoo> FooFactoryEx;
private static readonly IFactory<IBar> BarFactoryEx;
static UniversalFactory()
{
// These bindings could also be provided via a DI framework like Ninject.
FooFactoryEx = new FooFactory();
BarFactoryEx = new BarFactory();
}
// Maps concrete objects to factories according to the interface(s) they implement.
public static TConcreteType Create<TConcreteType>(int id)
{
if (typeof(TConcreteType).IsAssignableFrom(typeof(IFoo)))
return FooFactoryEx.Create<TConcreteType>(id);
if (typeof(TConcreteType).IsAssignableFrom(typeof(IBar)))
return BarFactoryEx.Create<TConcreteType>(id);
return default(TConcreteType);
}
}
같은 위의 외모에 대한 테스트 코드는 :
public class TestClass
{
public void TestMain()
{
var foo1 = UniversalFactory.Create<FooImpl>(1);
var foo2 = UniversalFactory.Create<FooImpl>(2);
var bar1 = UniversalFactory.Create<BarImpl>(1);
}
}
오류가 될 것으로 보인다 여기
The type 'TConcreteType' cannot be used as type parameter 'TConcreteType'
in the generic type or method 'Tests.IFactory<TFactoryType>.Create<TConcreteType>(int)'.
There is no boxing conversion or type parameter conversion from 'TConcreteType' to
'Tests.IFoo'.
샘플 코드의 중요한 부분입니다 TConcreteType은 다음 줄에 대해 IFoo로 제한되어야합니다.
return FooFactoryEx.Create<TConcreteType>(id);
동시에 동안 (엄청나게)이 라인 IBar로 제한 :
return BarFactoryEx.Create<TConcreteType>(id);
나는 내가 유형 검사를 할 수 있어요 이후이 제약없이 작동 할 것으로 예상했을 것이다 그러나 같은 :
if (typeof(TConcreteType).IsAssignableFrom(typeof(IFoo)))
그러나 제한이나 타입 캐스팅으로 인해 상황이 해결되지 않았습니다. 불가능한 일을하려고합니까? 아니면 아직 시도하지 않은 컴파일러 오류에서 암시 된 명백한 제한이 있습니까?
EDIT # 1 : "FooImpl : IFoo"및 "BarImpl : IBar"을 지적해야합니다.
는 는는 편집 # 2 : 내 예에서 중요한 형 제약 탈락하기 때문에이 정보는 크리스 마틴 (Chris Martin)이 추가되었다 : 내가 아는 한
public interface IFactory<in TFactoryType>
{
TConcreteType Create<TConcreteType>(int id) where TConcreteType : TFactoryType;
}
동의 함. 나는 어제 대화에서이 같은 결론을내는 것을 끝내었다. 어쨌든 모든 아이디어가 실제로 "똑똑한"것이기는하지만 원래의 방식은 약간 "똑똑"하지 않습니다. – jmsb