在C#中重建基类

时间:2015-04-24 16:55:51

标签: c# class casting derived-class base-class

在下面的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

3 个答案:

答案 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