Types c#4.0-重构块的最佳方法;如果(某物是类型){}";声明?
我有一些代码看起来像这样Types c#4.0-重构块的最佳方法;如果(某物是类型){}";声明?,types,c#-4.0,refactoring,Types,C# 4.0,Refactoring,我有一些代码看起来像这样 public void ResetControls(Control controlOnPage) { if (controlOnPage is TextBox) { ResetTextBoxControl(controlOnPage); } if (controlOnPage is MediaPicker) { ((MediaPicker)controlOnPage).Media = null;
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警告我“不要对这段代码进行不必要的强制转换”,但我不确定如何重写它以使其更好。有什么想法吗?为了避免重复的演员阵容,您可以将其转换为:
if (controlOnPage is MediaPicker)
{
((MediaPicker)controlOnPage).Media = null;
}
将是:
MediaPicker mediaPickerControl = controlOnPage as MediaPicker;
if (mediaPickerControl != null)
{
mediaPickerControl.Media = null;
}
重复你的其他演员
您还可以将其与一些嵌套的案例相结合,这样,如果您知道它已经是其他内容(例如文本框),您就不必尝试执行强制转换。最明显的做法是在
if
前面插入一个else
:
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
。我也会对它们进行排序,以便更多的常见情况出现在不常见情况之前。我认为FXCop不喜欢代码,因为一个很好的面向对象解决方案是将虚拟方法ResetControl
添加到控件
类中(当然,您不能这样做)
如果您想要一个清晰的面向对象解决方案,您可以创建一个接口IResetableControl
,并为实现该接口的每个控件创建一个派生类
如果您只是想使现有代码在语法上更好,可以使用以下帮助器方法:
public void IfCast<T>(object obj, Action<T> f) {
if (obj is T) f((T)obj);
}
这与您的原始代码具有完全相同的语义,但有点更好(我认为FxCop会接受它)。请注意,泛型类型参数是从lambda表达式中指定的类型推断出来的,例如(TextBox t)
。这还消除了在处理案例的代码内部执行额外强制转换的需要,因为您已经获得了正确类型的值(例如,mp
)。这将破坏“if control is SomeType”语句的(imho)可读链,并在if
之前隐藏强制转换中的类型问题。我不会说这是一种改进。@Johannes它确实消除了重复的强制转换。但是牺牲可读性来改进(可疑的)性能并不总是正确的。我想这也可以被编译器消除。@Johannes:我不认为这是被编译器消除的,但我同意,以你现在的方式编写它对读者来说更清晰。它将比Rowland的代码稍微慢一点,但这可能无关紧要。然而,罗兰的回答也将消除FXCop错误,因为这样你就可以施放一次而不是两次。@Johannes FXCop警告告诉你它还没有被编译器消除。正如我在我的帖子中提到的,总是有可能在某些条件逻辑中将这些链接起来。当然,可读性也是主观的。。。
IfCast(controlOnPage, (TextBox t) =>
ResetTextBoxControl(t));
IfCast(controlOnPage, (MediaPicker mp) => {
mp.Media = null; });