当IList by ref是方法签名时,通过ref传递List

时间:2014-07-25 15:18:05

标签: c# list ilist

我遇到以下代码的问题。我希望我的方法采用IList,而不是List但是我被误导了吗?

这是我的方法:

public void DoFoo( ref IList<Foo> thingy) {}

这是声明和电话:

var foo = new List<Foo>();
DoFoo( ref foo)

为什么不编译? foo肯定实现IList If是因为编译必须从List转换为IList?

2 个答案:

答案 0 :(得分:7)

类型推断妨碍了这里。 var相当于直接声明List,但您需要IList。您必须在声明中明确写出预期的类型。

IList<foo> foo = new List<Foo>();
DoFoo( ref foo)

答案 1 :(得分:4)

它没有编译的原因是ref允许该方法执行此操作:

public void DoFoo( ref IList<Foo> thingy)
{
    thingy = new Foo[10];
}

数组实现IList<T>,但它们不是List<T>,这就是编译器拒绝编译代码的原因。

您有一个参数引用特定类型的变量,在本例中为List<Foo>,并且您不能在其中填充其他类型的集合,除非它们从List<Foo>继承

一种方法可以绕过这个,只需将列表复制到正确类型的变量中,但您还需要确定如果实际替换方法会发生什么该变量的内容。

换句话说,你可以这样做:

IList<Foo> il = foo;
DoFoo(ref il);
// what if il is a new reference here now?

正如另一个答案中已经提到的,对象(以及在这种情况下的列表)已经是引用。您是否确定首先需要ref?让我澄清一下。 .NET中的对象是引用类型,这意味着您传递对该对象的引用。使用ref参数可以通过引用传递参数,这是不同的。

传递 引用允许该方法访问与外部世界相同的对象。通过引用传递允许该方法访问外部世界中的变量