在下面的C#设置中,从类X派生的类A和一些将List列表作为参数的方法,
class X
{...};
class A : X
{...};
List<A> listA;
List<X> listX;
void SomeMethod(ref List<X>)
{...};
有没有办法对A类使用相同的方法(从X派生)?重新建立从A到X的列表似乎不起作用。
SomeMethod(ref listX); // Works
SomeMethod(ref (List<X>)listA); // Does not work
答案 0 :(得分:4)
实际上,它已经有效,因为IEnumerable
在其泛型类型参数上是协变。
如果您修改这样的签名:
void SomeMethod(ref IEnumerable<X>)
{...};
然后你可以将List<X>
或 List<A>
传递给它,就可以了。
总而言之,你通过ref
传递它是非常奇怪的。您通常不会以这种方式传递引用类型。
答案 1 :(得分:3)
两种可能性。
一,将void SomeMethod(List<X> list)
重新定义为void SomeMethod(IEnumerable<X> list)
。
由于IEnumerable<T>
是协变的,因此您可以将IEnumerable<A>
传递给带有IEnumerable<X>
参数的方法,它会起作用。
两个,将void SomeMethod(List<X> list)
重新定义为void SomeMethod<T>(List<T> list) where T : X
。
您可以使用通用SomeMethod
来处理从X
派生的任何类型的列表,包括X
本身。
(如果你可以将方法定义为void SomeMethod<T>(List<T> list)
[没有where
]或者更好,那么更好的是SomeMethod<T>(IEnumerable<T> list)
,因为你有一个适用于比你目前想到的更多的情况,但我会假设你需要使用X
的某些功能,因此这些功能是不可行的。
另请注意,正如人们所说的那样ref
在这里很不寻常(我刚才把它拿出来),这也会导致更多问题。要使用ref
,您需要一个适当类型的可赋值变量(局部变量,参数,可设置属性或数组访问),因为ref
需要能够分配和访问。因此,即使ref
可以转换为SomeMethod(ref (List<X>)listA)
,也无法在listA
尝试传递List<X>
变量时进行转换(无论如何它都无法转换为{{1}}
答案 2 :(得分:1)
很抱歉回答不是您的直接问题。我建议你摆脱List&lt; A&gt;并使用List&lt; X&gt;这两个地方。创建A的实例并将它们添加到List&lt; X&gt;。
现在根据你的直接问题。当@BradleyDotNet回答时,这是可能的。有关详细信息和示例,请参阅此网址:https://msdn.microsoft.com/ru-ru/library/dd799517(v=vs.110).aspx