简体   繁体   English

将继承的接口传递给方法

[英]Pass inherited Interface to a method

I'm having the following interfaces: 我有以下界面:

public interface IBase
{
    int id1 { get; set; }
}

public interface IDerived : IBase
{
    int id2 { get; set; }
}

And the following (sample) program: 和以下(示例)程序:

class Program
{
    static void Main(string[] args)
    {
        IList<IDerived> derived = null;
        Check(derived);
    }

    static void Check(IList<IBase> base)
    {
    }
}

I'm getting this compliation error: cannot convert from ' System.Collections.Generic.IList<IDerived> ' to ' System.Collections.Generic.IList<IBase> ' 我收到此错误提示:无法从“ System.Collections.Generic.IList<IDerived> ”转换为“ System.Collections.Generic.IList<IBase>

If I'm trying to pass only one instance, and not a list, it's working, so what am I missing here? 如果我仅尝试传递一个实例,而不传递列表,则它正在运行,那么我在这里错过了什么?

Thanks, 谢谢,

This is due to a lack of covariance on interfaces types in C# 3, C# 4 will allow you to specify covariance and contravariance on interfaces types. 这是由于C#3中的接口类型缺少协方差,C#4将允许您指定接口类型的协方差和矛盾。

Unfortunately this is one of those things that just doesn't work the way you think it should in C# 3. 不幸的是,这只是您认为不应该在C#3中使用的方式之一。

You will need to cast the IList items to IBase. 您将需要将IList项目强制转换为IBase。 Here's an example using Linq extensions: 这是使用Linq扩展的示例:

Check(derived.Cast<IBase>());

An instance of IList<IDerived> is not an instance of IList<IBase> . IList<IDerived>的实例不是IList<IBase>的实例。 For one thing, you can't call .Add(new ConcreteBase()) on it. 一方面,您无法在其上调用.Add(new ConcreteBase()) (where ConcreteBase implements IBase ) (其中ConcreteBase实现IBase

And yet this would work... 但这行得通...

    static void Main(string[] args)
    {
        List<IDerived> derived = null;
        Check(derived.ToArray());
    }

    static void Check(IBase[] asdf)
    {
    }

One of several reasons I prefer the raw array [] or IEnumerable<> for interfaces both on arguments and return values. 我偏爱原始数组[]或IEnumerable <>作为参数和返回值接口的几种原因之一。 But if you prefer using List/IList you can still do the following: 但是,如果您更喜欢使用列表/ IList,则仍然可以执行以下操作:

    static void Main(string[] args)
    {
        IList<IDerived> derived = null;
        Check(derived);
    }

    static void Check<T>(IList<T> asdf) where T : IBase
    {
    }

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

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