이상한 반사 문제가 있습니다.리플렉션을 사용하여 T 유형의 인터페이스를 구현하는 클래스를 만들려면
인터페이스 IFooAttempt1
을 구현하는 클래스 FooAttempt1
을 참조하십시오.이 인터페이스는 IAnimal
을 반환하는 속성이 있습니다. FooAttempt1
의 경우 Dog
을 반환합니다.
해당 프로그램에서 IFooAttempt1
을 구현하는 클래스는 인스턴스화 된 다음 작업을 수행 한 후 자체 반영 유형과 키를 나중에 리플렉션을 사용하여 다시 수분 저장합니다. IFooAttempt1
을 구현하는 많은 클래스가 있으며 아주 잘 작동하는 아키텍처입니다.
기본 프로세스는 Attempt1()
메서드에서 확인할 수 있습니다.
실제 클래스는 IFooAttempt1
보다 약간 복잡하며 실수를하기 쉽습니다. 따라서 우리는 코드를 리팩터링하여 제네릭을 사용하여 이러한 클래스가 올바르게 구현되도록합니다.
일반 interface IFooAttempt2 <T> where T : IAnimal
을 구현하는 FooAttempt2
을 참조하십시오.
이 기능적으로 동일 동물의 속성은 이제
public Dog Animal
보다는
두IFooAttempt1
public IAnimal Animal
및 IFooAttempt2
로 정의되어 있지만 제네릭의 자동 문서화 기능은 우리가 오히려 더 구현하게 보장 복잡한 클래스는 매우 간단합니다.
Attempt2()
코드를 참조 할 때 문제가 발생합니다. 반사를 사용하는 경우 FooAttempt2
라인을
object o = constructor.Invoke(null);
IFooAttempt2<IAnimal> foo2 = (IFooAttempt2<IAnimal>) o;
표시 오류
An unhandled exception of type 'System.InvalidCastException' occurred in
ConsoleApplication1.exe Additional information: Unable to cast object of
type 'ConsoleApplication1.FooAttempt2' to type 'ConsoleApplication1.IFooAttempt2`1
[ConsoleApplication1.IAnimal]'.
나는 그 점을 이해할 수 있지만 방법이 반사를 사용 하는가를 다시? 직접 실행 창에
, 당신은
? o
{ConsoleApplication1.FooAttempt2}
Animal: {ConsoleApplication1.Dog}
를 이동하는 경우가 있으므로 정확하게 반영하고있다. FooAttempt2
이 IFooAttempt2<Dog>
으로 정의 된 경우에도 (IFooAttempt2<IAnimal>
)로 변환 할 수 없습니다. 여기서 Dog
은 IAnimal
입니다.
내 즉각적인 생각이
Type type = assembly.GetType(className, false, true).MakeGenericType(new[] { typeof(IAnimal) });
을하려고했지만 그것은 컴파일되지 않습니다. 분명히 컴파일러는 싫어한다. typeof(interface)
이 단계에서 나는 완전히 붙어있다.
감사합니다.
public interface IFooAttempt2<out T>
where T : IAnimal
{
T Animal
{
get;
}
}
다음
IFooAttempt2<IAnimal>
에 캐스트가 성공 :
class Program
{
static void Main(string[] args)
{
Attempt1();
Attempt2();
}
static void Attempt1()
{
FooAttempt1 foo = new FooAttempt1();
Console.WriteLine(foo.Animal.MakeNoise());
string className = foo.GetType().FullName;
// -----
// get the assembly
Assembly assembly = typeof(FooAttempt1).Assembly;
// get the class
Type type = assembly.GetType(className, false, true);
// create an instance
ConstructorInfo constructor = type.GetConstructor(new Type[] { });
IFooAttempt1 foo2 = (IFooAttempt1)constructor.Invoke(null);
Console.WriteLine(foo2.Animal.MakeNoise());
}
static void Attempt2()
{
FooAttempt2 foo = new FooAttempt2();
Console.WriteLine(foo.Animal.MakeNoise());
string className = foo.GetType().FullName;
// -----
// get the assembly
Assembly assembly = typeof(FooAttempt2).Assembly;
// get the class
Type type = assembly.GetType(className, false, true);
// create an instance
ConstructorInfo constructor = type.GetConstructor(new Type[] { });
object o = constructor.Invoke(null);
IFooAttempt2<IAnimal> foo2 = (IFooAttempt2<IAnimal>) o; // << PROBLEM HERE
Console.WriteLine(foo2.Animal.MakeNoise());
}
}
public interface IAnimal
{
string MakeNoise();
}
public class Dog : IAnimal
{
public string MakeNoise()
{
return "Bark";
}
}
public interface IFooAttempt1
{
IAnimal Animal
{
get;
}
}
public class FooAttempt1 : IFooAttempt1
{
public FooAttempt1()
{
}
public IAnimal Animal
{
get
{
return new Dog();
}
}
}
public interface IFooAttempt2<T>
where T : IAnimal
{
T Animal
{
get;
}
}
public class FooAttempt2 : IFooAttempt2<Dog>
{
public FooAttempt2()
{
}
public Dog Animal
{
get
{
return new Dog();
}
}
}
잘 쓰여진 질문입니다. – aevitas