我有一些看起来像这样的代码,
public void ResetControls(Control controlOnPage)
{
if (controlOnPage is TextBox)
{
ResetTextBoxControl(controlOnPage);
}
if (controlOnPage is MediaPicker)
{
((MediaPicker)controlOnPage).Media = null;
}
if (controlOnPage is RelatedContentPicker)
{
((RelatedContentPicker)controlOnPage).RelatedContentCollection = null;
}
...
...
foreach (Control child in controlOnPage.Controls)
{
ResetControls(child);
}
}
它背后的想法是我可以将一个页面传递给该方法,它会递归地将其上的所有控件重置为默认状态 - 在MediaPicker和RelatedContentPicker的情况下,这些是我创建的用户控件
FXCop警告我“不要不必要地投射”这个代码 - 但我不确定如何重写它以使其更好。有什么想法吗?
答案 0 :(得分:2)
我认为FXCop不喜欢代码,因为一个很好的面向对象的解决方案是将虚拟方法ResetControl
添加到Control
类(你当然不能这样做) 。
如果你想要一个清晰的面向对象的解决方案,你可以创建一个接口IResetableControl
并为每个实现该接口的控件创建一个派生类。
如果您只想让现有代码在语法上更好,可以使用以下辅助方法:
public void IfCast<T>(object obj, Action<T> f) {
if (obj is T) f((T)obj);
}
然后你可以写:
IfCast(controlOnPage, (TextBox t) =>
ResetTextBoxControl(t));
IfCast(controlOnPage, (MediaPicker mp) => {
mp.Media = null; });
这与原始代码具有完全相同的语义,但它更好一些(我认为FxCop会接受它)。请注意,泛型类型参数来自lambda表达式中指定的类型,例如(TextBox t)
。这也消除了在处理案例的代码中进行额外强制转换的需要,因为您已经获得了正确类型的值(例如mp
)。
答案 1 :(得分:1)
最明显的事情是在else
的前面加if
:
if (controlOnPage is TextBox)
{
ResetTextBoxControl(controlOnPage);
}
else if (controlOnPage is MediaPicker)
{
((MediaPicker)controlOnPage).Media = null;
}
else if (controlOnPage is RelatedContentPicker)
{
((RelatedContentPicker)controlOnPage).RelatedContentCollection = null;
}
如果控件是MediaPicker
,则无需尝试强制转换为RelatedContentPicker
或TextBox
。我也会订购它们,以便在不太常见的案例之前出现更多常见案例。
答案 2 :(得分:0)
为避免重复播放,您可以对此进行转换:
if (controlOnPage is MediaPicker)
{
((MediaPicker)controlOnPage).Media = null;
}
是:
MediaPicker mediaPickerControl = controlOnPage as MediaPicker;
if (mediaPickerControl != null)
{
mediaPickerControl.Media = null;
}
重复你的其他演员。
你也可以将它与一些嵌套的案例结合起来,这样你就不必尝试进行演员表,如果你知道它已经是其他东西,比如文本框