【问题标题】:C# The is no implicit reference conversion from 'B' to 'A' using GenericsC# 没有使用泛型从“B”到“A”的隐式引用转换
【发布时间】:2015-04-07 19:31:32
【问题描述】:

我在使用泛型从派生类型转换为基类型时遇到问题。

管理字典的类:

public class ManagerDictionary<TContext>
{
    public ManagerDictionary()
    {    
        this.Dictionary = new Dictionary<int, TContext>();
    }

    public IDictionary<int, TContext> Dictionary { get; private set; }

    public void Register<TSubContext>(int context, TSubContext subContext) where TSubContext : TContext
    {
        this.Dictionary[context] = subContext;
    }
}

进程上下文的接口:

public interface IProcessContext : IContext<ProcessViewModel>
{
}

我的测试课:

public class Foo<TViewModelContext> where TViewModelContext : ViewModeBase
{
    public Foo(IProcessContext processContext)
    {
        // Create de Dictionary Manager.
        this.ManagerDictionary = new ManagerDictionary<IContext<TViewModelContext>>();

        // Register the process context on dictionary.
        // The error is occurring here: The is no implicit reference conversion from 'IProcessContext' to 'IContext<TViewModelContext>'
        this.ManagerDictionary.Register((int)ContextType.Process, processContext);
    }

    protected ManagerDictionary<IContext<TViewModelContext>> ManagerDictionary { get; set; }
}

当我尝试注册processContext时,出现问题:

'IProcessContext' 到没有隐式引用转换 IContext&lt;TViewModelContext&gt;

我该如何解决这个问题?

编辑:

当我创建 Foo 的继承类时,我可以注册,但我也需要在 Foo 类上注册。

public interface IAnotherProcessContext : IContext<ProcessTwoViewModel>
{
}

public class InheritedFoo : Foo<ProcessTwoViewModel>
{
    public InheritedFoo(IAnotherProcessContext anotherProcessContext)
    {
        base.ManagerDictionary.Register((int)ContextType.InheritedProcess, anotherProcessContext);
    }
}

【问题讨论】:

    标签: c# asp.net-mvc-3 generics


    【解决方案1】:

    您试图将IContext&lt;T&gt; 视为与T 是协变的,但该接口未定义为协变的。

    要么使接口协变,要么改变你的程序,使你永远不会期望 IContext&lt;Child&gt; 可以隐式转换为 IContext&lt;Parent&gt;

    【讨论】:

    • 但是当我尝试创建另一个继承了 'Foo' 的类并尝试注册时,它成功了,为什么?
    • @RenatoLeite 不知道你在做什么,具体来说,我不能说。
    • 这似乎并不准确。 IProcessContext 通过继承隐含为 IContext&lt;ProcessViewModel&gt;。类型参数TViewModelContext 通过泛型约束隐含为ViewModeBase。我们假设ProcessViewModelViewModelBase(他们的名字就是这样)。所以我们有一个类的两个不同的“专业化”,ViewModelBaseIContext&lt;&gt; 的协方差和反方差都不能帮助 IContext&lt;X&gt;IContext&lt;Y&gt; 之间的隐式转换,因为关于类型 XY 的所有已知信息是它们都专门化同一个类 B
    • @RenatoLeite 为什么这不是预期的?当您尝试将IContext&lt;Something&gt; 视为IContext&lt;Something&gt; 时,它会起作用,因为它确实是IContext&lt;Something&gt;,而当您尝试将其视为IContext&lt;SomethingElse&gt; 时,它不会,因为它不是那个东西。一切都应该如此。
    • @JeppeStigNielsen 你是对的;我没有注意到这一点。你为什么不把它写下来作为答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    相关资源
    最近更新 更多