[英]C# - creating a class whose constructor takes generic param results in casting exception
I have IInfo
and its generic version: 我有
IInfo
及其通用版本:
public interface IInfo
{
IInput Input { get; }
}
public interface IInfo<T> : IInfo where T : IInput
{
new T Input { get; }
}
Class implementation: 类的实现:
public class Info : IInfo<IInput>
{
public IInput Input { get; }
public Info (IInput input) {}
}
Factory to create IOutput from IInput: 从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});
}
}
To test the above code: 要测试上面的代码:
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);
}
I get the following error: 我收到以下错误:
Object of type 'Info' cannot be converted to type'Info<TestInput>'.
Side note: I'm open to any suggestions to simplify/re-write the code in a different way. 旁注:我愿意接受任何以不同方式简化/重写代码的建议。
public TestOutput(IInfo<TestInput> info)
{
}
Is expecting an IInfo<TestInput>
explicitly . 明确期望
IInfo<TestInput>
。 However, you're trying to call it with IInfo<IInput>
(which is what Info
is designed to be). 但是,您尝试使用
IInfo<IInput>
(这是Info
的设计目标)来调用它。
To make it clear, you could also write: 为了清楚起见,您还可以编写:
IInput input = new OtherInput();
IInfo info = new Info(input);
var factory = new GenericFactory<TestInput, TestOutput>();
IOutput output = factory.Create(info);
And now you've provided IInfo<OtherInput>
to something expecting IInfo<TestInput>
现在您提供
IInfo<OtherInput>
的东西期待IInfo<TestInput>
You would need to make IInfo<T>
contravariant to allow it to be cast, for example: 您需要做
IInfo<T>
逆变允许它定投,例如:
public interface IInfo<in T> : IInfo
where T : IInput
{
//new T Input { get; }
}
But note that it's illegal to return T
when with a contravariant interface. 但是请注意,使用逆接口时返回
T
是非法的。 The alternative is to make Info
generic, and change Create
to accept IInfo<TInput>
. 另一种方法是使
Info
通用,并更改Create
以接受IInfo<TInput>
。 That latter gives you the benefit of a compile-time error when trying to pass IInfo<OtherInput>
to Create()
, rather than a run-time error 当尝试将
IInfo<OtherInput>
传递给Create()
,后者会给您带来编译时错误的好处,而不是运行时错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.