将子类转换为父类

时间:2009-07-19 11:27:41

标签: c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List list = new List();
            list.Add(new A());

            var list2 =
                from p in list
                select p as B;

            Console.WriteLine(list2.First().myString);
            Console.ReadLine();
        }
    }

    class A
    {
        public string myString = "abc";
    }

    class B : A
    {

    }
}

我该如何解决这个问题? 感谢

5 个答案:

答案 0 :(得分:4)

你做不到;该列表包含A的实例,您不能将A转换为B.您只能在继承链中“向上”转换,而不能向下转换。因此,如果您在代码中更改A和B上的位置,则可以正常工作:

class Program
{
    static void Main(string[] args)
    {
        List<B> list = new List<B>();
        list.Add(new B());

        var list2 =
            from p in list
            select p as A;

        Console.WriteLine(list2.First().myString);
        Console.ReadLine();
    }
}

class A
{
    public string myString = "abc";
}
class B : A { }

如果要转换到另一个方向,则需要编写转换代码:

class Program
{
    static void Main(string[] args)
    {
        List<A> list = new List<A>();
        list.Add(new B());

        var list2 = list.ConvertAll<B>(a => B.FromA(a));

        Console.WriteLine(list2.First().myString);
        Console.ReadLine();
    }
}

class A
{
    public string myString = "abc";
}

class B : A
{
    public B() { }

    public static B FromA(A fromInstance)
    {
        B result = new B();
        result.myString = fromInstance.myString;
        return result;
    }
}

答案 1 :(得分:1)

list2.First().myString会尝试在myString引用上访问null。如果您无法投射,as运算符将返回null。面向对象的设计原则告诉我们,您可以在任何可以使用超类的地方使用子类周围。因此,您正在使用A的实例填充列表,并尝试将其转换为B。但它们根本不是B的实例,因此强制转换将始终失败(并且,因为您使用as,所以返回null)。

答案 2 :(得分:0)

你的程序确实“将父类改为儿子类”,与你的问题标题相反。无论如何,这是无法做到的。

澄清一下:

尝试将B类更改为以下内容:

class B : A
{
    public string MyStringB { get; set; }
}

如果你能够将A转换为B,那么myStringB值是什么,因为它从未在A上定义过?

答案 3 :(得分:0)

在B类中创建一个构造函数,它接受一个A类的实例。

答案 4 :(得分:0)

您可以创建一个复制构造函数,该构造函数接受类型为A的对象:

class B : A
{
    public B(A copy) {
        myString = copy.myString;
    }
}

然而,我对LINQ并不太熟悉,所以我不确定如何让它自动使用它。