c# - 将泛型类转换为其基类非泛型类

时间:2009-04-02 15:08:16

标签: c# generics

我有以下课程:

public abstract class CustomerBase
{
    public long CustomerNumber { get; set; }
    public string Name { get; set; }
}

public abstract class CustomerWithChildern<T> : CustomerBase
    where T: CustomerBase
{
    public IList<T> Childern { get; private set; }

    public CustomerWithChildern()
    {
        Childern = new List<T>();
    }
}

public class SalesOffice : CustomerWithChildern<NationalNegotiation>
{
}

SalesOffice只是代表不同级别的客户层次结构的少数几个类别之一。现在我需要从某个角度(CustomerBase)遍历这个层次结构。我不知道如何在不使用反射的情况下实现。我想实现类似的东西:

    public void WalkHierarchy(CustomerBase start)
    {
        Print(start.CustomerNumber);
        if (start is CustomerWithChildern<>)
        {
            foreach(ch in start.Childern)
            {
                WalkHierarchy(ch);
            }
        }
    }

我有没有机会得到这样的工作?


该解决方案基于我实现的has-childern接口:

public interface ICustomerWithChildern
{
    IEnumerable ChildernEnum { get; }
}

public abstract class CustomerWithChildern<T> : CustomerBase, ICustomerWithChildern
    where T: CustomerBase
{
    public IEnumerable ChildernEnum { get { return Childern; } }

    public IList<T> Childern { get; private set; }

    public CustomerWithChildern()
    {
        Childern = new List<T>();
    }
}

    public void WalkHierarchy(CustomerBase start)
    {
        var x = start.CustomerNumber;
        var c = start as ICustomerWithChildern;
        if (c != null)
        {
            foreach(var ch in c.ChildernEnum)
            {
                WalkHierarchy((CustomerBase)ch);
            }
        }
    }

6 个答案:

答案 0 :(得分:7)

您可以将WalkHierarchy方法移动到基类并使其成为虚拟。基类实现只处理当前节点。对于CustomerWithChildern<T>类,覆盖将执行实际操作。

答案 1 :(得分:3)

试试这个:

if(start.GetType().GetGenericTypeDefinition() == typeof(CustomerWithChildern<>))

答案 2 :(得分:2)

“Is”和“As”仅适用于完全限定的泛型类型。

有关详细信息,包括解决方法,请参阅this MSDN discussion

我见过的最常见的解决方法是在CustomerWithChildren可以实现的混合中添加一个接口,并检查该接口。

答案 3 :(得分:2)

我相信你想查找确定对步行界面做的事情。

因此,可以添加一个“IWalkable”接口来公开执行walk所需的信息,然后您可以创建方法检查以查看传递的对象是否实现了接口。

答案 4 :(得分:1)

我认为在第一次使用泛型类时,每个人都会遇到这个“问题”。

你的第一个问题在你的问题中被暗示:一个开放的泛型类型不是封闭的类型的基类。根本没有OO关系。真正的基类是CustomerBase。 “开放”泛型类似于半完成类;指定类型参数“关闭”它,使其完整。

虽然你能做到:

Type t = typeof(CustomerWithChildern<>)

条件

typeof(CustomerWithChildern<>).IsAssignableFrom(CustomerWithChildern<Foo>)

永远是假的。

-Oisin

答案 5 :(得分:0)

明确地使用该方法,没有。但是,您可以使用界面实现相同的功能。实际上,您可以让您的泛型类实现IEnumerable。同样值得注意的是,您的班级也应该有“T:CustomerBase”,以确保类型安全。

相关问题