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

时间:2016-06-08 15:14:55

标签: c# generics interface

我正在尝试在基类上设置一个值,但我收到了错误:

  

无法将'PersonService'类型隐式转换为   'IMyInterface<IEntity>'。存在显式转换(是你   错过演员?)

当我尝试创建PersonService()时,它会实现IMyInterface<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();
    }
}

3 个答案:

答案 0 :(得分:5)

IMyInterface<Person>不一定与IMyInterface<IEntity>兼容。如果IMyInterface包含.Add(T item)方法怎么办?如果您被允许通过IMyInterface<IEntity>拨打那些不是Person的内容,则该集合最终会出现无效元素,违反了类型安全。

但是如果IMyInterface不包含这样的方法,它总是安全的呢?在这种情况下,您可以通过使用covariant类型告诉编译器:

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

现在你的例子将编译。

答案 1 :(得分:2)

你需要让你的界面共变(如果可能的话):

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

然后你就能做到:

DataService = new PersonService();

答案 2 :(得分:0)

因为DataService期待IMyInterface<IEntity>而不是IMyInterface<Person>

关于协方差的其他答案是解决这个问题的好方法 - 另一个是引入一些泛型。

如果您更改此类Model以指定实体类型

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

Test是这样的:

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

一切按预期工作:

http://rextester.com/EVBT53292