C# - 创建一个类,其构造函数采用泛型参数导致转换异常

时间:2016-12-01 04:17:51

标签: c# generics interface casting

我有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>'.

附注:我打算以任何方式简化/重写代码。

1 个答案:

答案 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()时,后者会为您带来编译时错误,而不是运行时错误