简体   繁体   English

使用泛型时无法隐式转换类型

[英]Cannot implicitly convert type when using generics

I am trying to set a value on a base class but am getting the error: 我试图在基类上设置一个值,但出现错误:

Cannot implicitly convert type 'PersonService' to 'IMyInterface<IEntity>' . 无法将类型'PersonService'隐式转换为'IMyInterface<IEntity>' An explicit conversion exists (are you missing a cast?) 存在显式转换(您是否缺少演员表?)

When I try to create my PersonService() it does implement IMyInterface<Person> . 当我尝试创建我的PersonService()它确实实现了IMyInterface<Person> Person implements IEntity so I can't work out why it is not working. Person实现了IEntity所以我无法弄清为什么它不起作用。

public interface IEntity { }
public class Person : IEntity { }
public interface IMyInterface<T> where T : IEntity { }
public class PersonService : IMyInterface<Person> { }
public abstract class Model : IEntity
{
    public IMyInterface<IEntity> DataService { get; set; }
}
public class Test : Model
{
    public Person Person { get; set; }
    public Test() : base()
    {
        DataService = new PersonService();
    }
}

An IMyInterface<Person> isn't necessarily compatible with an IMyInterface<IEntity> . IMyInterface<Person>不一定与IMyInterface<IEntity>兼容。 What if IMyInterface contains an .Add(T item) method? 如果IMyInterface包含.Add(T item)方法怎么办? If you were allowed to call that through IMyInterface<IEntity> for something that's not a Person , the collection would end up with an invalid element, violating type safety. 如果允许您通过IMyInterface<IEntity>调用不是Person ,则该集合将以无效元素结尾,从而违反类型安全性。

But what if IMyInterface contains no such methods, and it's always safe? 但是,如果IMyInterface包含此类方法,并且始终安全,该怎么办? In that case you can tell the compiler that by using a covariant type: 在那种情况下,您可以通过使用协变类型来告诉编译器:

public interface IMyInterface<out T> where T : IEntity { }

And now your example will compile. 现在,您的示例将编译。

You need to make your interface co-variant (if it's possible): 您需要使接口协变(如果可能):

public interface IMyInterface<out T> where T : IEntity { }

Then you would be able to do: 然后,您将可以执行以下操作:

DataService = new PersonService();

Because DataService is expecting an IMyInterface<IEntity> not an IMyInterface<Person> . 因为DataServiceIMyInterface<IEntity>而不是IMyInterface<IEntity> IMyInterface<Person>

Other answers regarding covariance are a great way to solve this - another is to introduce some generics. 关于协方差的其他答案是解决此问题的好方法-另一个是引入一些泛型。

If you change Model like this to specify the type of entity 如果您像这样更改Model以指定实体的类型

public abstract class Model<TEntity> : IEntity 
            where TEntity : IEntity
{
    public IMyInterface<TEntity> DataService { get; set; }
}

and Test like this: 并像这样Test

public class Test : Model<Person>
{
    public Person Person { get; set; }
    public Test() : base()
    {
        DataService = new PersonService();
    }
}

All works as expected: 所有工作均符合预期:

http://rextester.com/EVBT53292 http://rextester.com/EVBT53292

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM