想象一下,你有一堆BaseType对象,你必须对所有DerivedType B,C或D(并丢弃其他所有东西)做动作A.而且你不能对BaseType实例这样做,因为它没有你需要的方法。在我的情况下,我需要在ASP.NET Webforms页面上为某个类型的所有控件分配一个类,代码如下所示:
if (myControl != null)
{
foreach (var input in myControl.Controls.OfType<TextBox>())
{
input.CssClass = "my-class";
}
foreach (var input in myControl.Controls.OfType<DropDownList>())
{
input.CssClass = "my-class";
}
foreach (var input in myControl.Controls.OfType<RadioButtonList>())
{
input.CssClass = "my-class";
}
foreach (var input in myControl.Controls.OfType<CheckBox>())
{
input.CssClass = "my-class";
}
}
另一种方法是循环遍历所有myControl.Controls并检查对于每个控件是否为DerivedType X的控件是否为null,并且每个DerivedType我都感兴趣...所有那些做同样的事情到他们每个人。
我想知道我是否遗漏了一些明显的东西(或者我是不是完全理解多态性是如何工作的)。 This question提供了有关如何为自定义类执行此操作的一般概念,但遗憾的是我仍然坚持使用Control。
有没有更优雅的方式来完成上述任务?
提前谢谢!
答案 0 :(得分:1)
其实非常简单。
您要运行的代码是......
foreach(var child in control.Controls)
{
var webChild = child as WebControl;
if(webChild == null) return;
webChild.CssClass = "Foo";
}
然而,Linq已经有了一个&#34; try-cast,filter&#34;方法称为.OfType<>()
。
您可以像这样使用
foreach(var child in control.Controls.OfType<WebControl>())
{
child.CssClass = "Foo";
}
我建议您在尝试使用多态时查看类层次结构。您应该使用Object Browser
或MSDN引用。
那应该告诉你,你所看到的所有类都继承了WebControl,并且在这个类中可以设置.CssClass
。
答案 1 :(得分:-1)
这是在没有其他代码修改的情况下执行所需操作的最简单方法,因此您是正确的循环和检查控件是否是您正在寻找的派生类型之一。
for(int i = 0; i < myControl.Controls.Length; i++)
{
if(myControl.Controls[i] is TextBox || myControl.Controls[i] is DropDownList ||
myControl.Controls[i] is RadioButtonList || myControl.Controls[i] is Checkbox)
{
var webControl = myControl.Controls[i] as WebControl;
webControl.CssClass = "my-class";
}
}