动态派生类型参数
问题描述:
我正在使用对象树的递归函数。也就是说,我的对象集合是这样的:动态派生类型参数
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)
)
答
首先,因为它的立场,你不使用的类型参数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 + "'.");
}
边注:避免'as'投,如果情况下,你不立即检查空当你转换一个完全理解的转换异常成空裁判例外,经常在代码网站unrelate d演员。 –
另一方面说明:在验证项目列表中的第一个项目之后,您的循环会返回。我想如果'Validate'返回false,那么你只想返回,以便剩下的项目得到验证。就目前而言,你会在第一片叶子上得到结果。 –
看起来你不需要任何泛型:用'TreeNodeBase'替换'T',事情就会起作用。 – dasblinkenlight