本文介绍了c#4.0-重构"If(something is Type){}"块的最佳方法;陈述?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些看起来像这样的代码

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){}"块的最佳方法;陈述?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 08:33