动态导出通用类型参数

时间:2011-12-13 15:25:06

标签: c# generics recursion

我正在使用对象树的递归函数。也就是说,我的对象集合如下:

Object1
--Object2
----Object3
------Object4

所有对象都继承自基础对象(抽象类),其中包含Validate()方法,其集合继承自ITreeCollection。我编写了一个递归函数来执行:

private bool Validate<T>(ITreeCollection items) where T : TreeNodeBase
        {
            foreach (var itm in items as Collection<T>)
            {
                if (((TreeNodeBase)itm).Items != null)
                {
                    return Validate<T>(((TreeNodeBase)itm).Items);
                }
                else return true;
            }
            return true;
        }

如何导出内部函数的类型参数T(即return Validate<T>(((TreeNodeBase)itm).Items)

1 个答案:

答案 0 :(得分:2)

首先,就目前而言,您没有使用类型参数T,因此可以安全地删除它。但是我想你可能想要做一些特定类型的验证,所以这可能不是一个有用的建议。但是,如果没有您想对T做什么的例子,很难提出建议。

无论如何,这是我想要做的想法的一种方法:

private bool Validate(ITreeCollection items)
{
    foreach (TreeNodeBase node in (IEnumerable) items)
    {
        // validate the node itself first
        if (!Validate(node))
        {
            return false;
        }

        if (node.Items != null)
        {
            // validate its children
            if (!Validate(node.Items)
            {
                return false;
            }
        }
    }

    return true;
}

private bool Validate(TreeNodeBase node)
{
    if (node is BananaNode)
    {
        var bananaNode = (BananaNode) node;
        //TODO do BananaNode specific validation
    }
    else if (node is AppleNode)
    {
        var appleNode = (AppleNode) node;
        //TODO do AppleNode specific validation
    }
    else
    {
        throw new ArgumentOutOfRangeException("Cannot validate node of type '" + node.GetType().Name + "'.");
    }
}

你可以使用动态关键字变得时髦,并摆脱一些这种类型的检查,但它确实有点令人困惑,我建议反对它:

private bool Validate(ITreeCollection items)
{
    foreach (TreeNodeBase node in (IEnumerable) items)
    {
        // validate the node itself first
        if (!Validate((dynamic) node)) // this will call the most appropriate version of Validate
        {
            return false;
        }

        if (node.Items != null)
        {
            // validate its children
            if (!Validate(node.Items)
            {
                return false;
            }
        }
    }

    return true;
}

private bool Validate(BananaNode node)
{
    //TODO do BananaNode specific validation
}

private bool Validate(AppleNode node)
{
    //TODO do AppleNode specific validation
}

private bool Validate(TreeNodeBase node)
{
    throw new ArgumentOutOfRangeException("Cannot validate node of type '" + node.GetType().Name + "'.");
}