问题描述
我有一些看起来像这样的代码
I've got some code that looks like this,
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的情况下,这些是我创建的用户控件
The idea behind it is that I can pass a page to the method and it'll recursively reset all the controls on it to their default states - in the case of MediaPicker and RelatedContentPicker, these are user controls that I've created.
FXCop针对此代码警告我不要强制转换"-但我不确定如何重写它以使其变得更好.有什么想法吗?
FXCop warns me "Do Not Cast Unnecessarily" for this code - but I'm unsure how to rewrite it to make it better. Any ideas?
推荐答案
我认为FXCop不喜欢该代码,因为一个不错的面向对象的解决方案是将虚拟方法 ResetControl
添加到 Control
类(您当然不能这样做).
I think that FXCop doesn't like the code, because a nice object-oriented solution would be to add virtual method ResetControl
to the Control
class (which you, of course, cannot do).
如果您想要一个清晰的面向对象的解决方案,则可以创建一个接口 IResetableControl
,并为实现该接口的每个控件创建一个派生类.
If you wanted a clear object-oriented solution, you could create an interface IResetableControl
and create a derived class for each of the control that would implement the interface.
如果只想使现有代码在语法上更好,则可以使用以下帮助方法:
If you just want to make the existing code syntactically nicer, you can use the following helper method:
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
),因此这也消除了在处理案例的代码内进行其他强制转换的需要.
This has exactly the same semantics as your original code, but it is a bit nicer (and I think that FxCop will accept it). Note that the generic type parameter is infered from the type specified in the lambda expression e.g. (TextBox t)
. This also removes the need to do additional casting inside the code that handles the case, because you already get a value of the right type (e.g. mp
).
这篇关于c#4.0-重构"If(something is Type){}"块的最佳方法;陈述?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!