【问题标题】:Cannot Convert from error in simple class structure无法从简单类结构中的错误转换
【发布时间】:2023-03-06 08:54:01
【问题描述】:

我有以下类关系

    public interface ICapability
    {
    }

    public interface IBaseService<T> where T : ICapability
    {
    }

    public abstract class BaseService<out T> : IBaseService<T> where T : ICapability
    {
       // modified...
       T MapEventToCapability(dynamic eventData, T capability);
    }

    public class SomeCapability : ICapability
    {
    }

    public partial class Service1 : BaseService<SomeCapability>
    {
        public Service1()
        {
        }
    }

    public class ServiceResolver 
    {
        public void Register(BaseService<ICapability> serviceToRegister)
        {
        }
    }

我尝试调用 Register 方法,传入一个新的 service1,如下所示:

var b = new ServiceResolver();
var c = new Service1();

b.Register(c);

但是,我在调用 Register 时在 c 上遇到编译时错误,如下所示;

Cannot convert Service1 to BaseService<ICapability>

我假设因为 Service1 是 BaseService 类型,并且因为 SomeCapability 是 ICapability 类型,所以这不会是一个问题。

我也尝试转换为 BaseService,我尝试将 Register 上的输入参数更改为 IBaseService 并再次转换,但随后出现运行时错误。

【问题讨论】:

  • “协方差”是您要搜索的词
  • 如果在那个添加的方法中传递了一个能力,为什么你需要传递它?
  • 要清楚,如果方法是 T MapEventToCapability(dynamic eventData),它会工作得很好,因为它只会出去而不是进来。
  • @jamiec,我能够进行重构,以便将 T 删除为 only out。再次感谢您!

标签: c# class inheritance


【解决方案1】:

请注意,自发布此答案以来,该问题已更新 - 添加了不兼容的方法后,协方差不再是一个选项


你需要做两件事来完成这项工作

  1. 使Register 接受IBaseService&lt;ICapability&gt; 而不是BaseService&lt;ICapability&gt;
  2. 通过将泛型类型标记为out 使IBaseService 协变 - 这与您可以将List&lt;Foo&gt; 传递给期望IEnumerable&lt;Foo&gt; 的方法的原因相同,因为IEnumerable&lt;T&gt; 在类似的情况下是协变的方式。

public class ServiceResolver
{
    public void Register(IBaseService<ICapability> serviceToRegister)
    {
    }
}

public interface IBaseService<out T>
    where T : ICapability
{
}

现场示例:https://dotnetfiddle.net/O0yXa5

【讨论】:

  • 谢谢 Jamiec,这解决了我的问题
  • @JohnKears 很高兴我能帮上忙!
  • 我遇到了另一个小问题,注意我更新了 IBaseService 接口,添加了行 T MapEventToCapability(dynamic eventData, T capability); (见原帖)这显示了另一个错误,'参数'T'必须是逆变的......
  • @JohnKears 是的,你现在有一个 catch-22。如果你想要协方差,你不能传入一个实例,因此泛型类型上的 out 修饰符。 (我认为这可能会发生,但只能根据问题中的信息来回答)
  • 还是谢谢你。我应该在我的原始帖子中更加明确,我试图不要过度混乱这个问题。感谢您的帮助,因为我确实学到了一些新东西。我将您的回复标记为答案。干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 2020-08-14
  • 2012-08-15
相关资源
最近更新 更多