无法通过引用转换,装箱转换,取消装箱转换,换行转换或空类型转换来转换类型

时间:2015-06-17 10:01:33

标签: c# interface type-conversion

在C#中,如果我有参数类型是接口的函数的参数,那么如何传入实现接口的对象。

以下是一个例子:

函数的参数如下:

List<ICustomRequired>

我已经拥有的清单如下:

List<CustomObject> exampleList

CustomObject继承自ICustomRequired接口

exampleList作为参数传递的正确语法是什么?

这就是我想要完成上述任务的方式:

exampleList as List<ICustomRequired>

但是我收到以下错误:

  

无法通过引用转换,拳击转换转换类型,   取消装箱转换,包装转换或空类型转换

由于

3 个答案:

答案 0 :(得分:10)

您无法将List一种类型转换为其他类型的List

如果你想一想,你会很高兴你不能。想象一下,如果可能的话,你可能造成的破坏:

 interface ICustomRequired
 {
 }

 class ImplementationOne : ICustomRequired
 {
 }

 class ImplementationTwo: ICustomRequired
 {
 }

 var listOne = new List<ImplementationOne>();
 var castReference = listOne as List<ICustomRequired>();
 // Because you did a cast, the two instances would point
 // to the same in-memory object

 // Now I can do this....
 castReference.Add(new ImplementationTwo());

 // listOne was constructed as a list of ImplementationOne objects,
 // but I just managed to insert an object of a different type

但请注意,这行代码是合法的:

 exampleList as IEnumerable<ICustomRequired>;

这是安全的,因为IEnumerable没有为您提供任何添加新对象的方法。

IEnumerable<T>实际上定义为IEnumerable<out t>,这意味着类型参数为Covariant

您是否可以将功能参数更改为IEnumerable<ICustomRequired>

否则,您唯一的选择就是创建一个新列表。

var newList = (exampleList as IEnumerable<ICustomRequired>).ToList();

var newList = exampleList.Cast<ICustomRequired>().ToList();

答案 1 :(得分:0)

你不能这样做,你必须转换列表

exampleList.Cast<ICustomRequired>().ToList();

答案 2 :(得分:0)

List.Cast之外,C#的泛型为Covariance and contravariance提供了良好的支持。这个例子使它以我认为你最初想要的方式工作。

public class Program
{
    public static void Main()
    {
         Foo(new List<Fim>());
    }

    public static void Foo<T>(List<T> bar) where T : IFim
    {
        throw new NotImplementedException();
    }

    public class IFim{}
    public class Fim : IFim{}
}