我遇到以下代码的问题。我希望我的方法采用IList,而不是List但是我被误导了吗?
这是我的方法:
public void DoFoo( ref IList<Foo> thingy) {}
这是声明和电话:
var foo = new List<Foo>();
DoFoo( ref foo)
为什么不编译? foo肯定实现IList If是因为编译必须从List转换为IList?
答案 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
参数可以通过引用传递参数,这是不同的。
传递 引用允许该方法访问与外部世界相同的对象。通过引用传递允许该方法访问外部世界中的变量。