我有IInfo
及其通用版本:
public interface IInfo
{
IInput Input { get; }
}
public interface IInfo<T> : IInfo where T : IInput
{
new T Input { get; }
}
班级实施:
public class Info : IInfo<IInput>
{
public IInput Input { get; }
public Info (IInput input) {}
}
工厂从IInput创建IOutput:
public class GenericFactory<TInput, TOutput> where TInput : IInput where TOutput : IOutput
{
public IOutput Create(IInfo info)
{
ConstructorInfo cInfo = typeof(TOutput).GetConstructor(new[] { typeof(IInfo<TInput>) });
object output = cInfo.Invoke(new object[] {cInfo});
}
}
测试上面的代码:
public class TestInput : IInput
{
}
public abstract class AbstractOutput<TInput> : IOutput where TInput : IInput
{
}
public class TestOutput: AbstractOutput<TestInput>
{
public TestOutput(IInfo<TestInput> info)
{
}
}
public void Test()
{
IInput input = new TestInput();
IInfo info = new Info(input);
var factory = new GenericFactory<TestInput, TestOutput>();
IOutput output = factory.Create(info);
}
我收到以下错误:
Object of type 'Info' cannot be converted to type'Info<TestInput>'.
附注:我打算以任何方式简化/重写代码。
答案 0 :(得分:1)
public TestOutput(IInfo<TestInput> info)
{
}
明确期待IInfo<TestInput>
。但是,您尝试使用IInfo<IInput>
调用它(Info
设计为{。}}。
为了说清楚,你也可以写:
IInput input = new OtherInput();
IInfo info = new Info(input);
var factory = new GenericFactory<TestInput, TestOutput>();
IOutput output = factory.Create(info);
现在你已经为期待IInfo<OtherInput>
IInfo<TestInput>
您需要制作IInfo<T>
逆变以允许其投射,例如:
public interface IInfo<in T> : IInfo
where T : IInput
{
//new T Input { get; }
}
但请注意,使用逆变接口返回T
是违法的。另一种方法是使Info
通用,并将Create
更改为接受IInfo<TInput>
。在尝试将IInfo<OtherInput>
传递给Create()
时,后者会为您带来编译时错误,而不是运行时错误