根据类型和参数列表删除ifs

use*_*618 12 c# refactoring if-statement

我想重构以下递归方法:

public static void Initialize(Control control, DocumentContainer container, ErrorProvider provider)
{
    if (control == null)
    {
        return;
    }

    var controlWithTextBase = control as ICustomControlWithText;
    if (controlWithTextBase != null)
    {
       controlWithTextBase.DocumentLoaded = true;
       controlWithTextBase.Initialize(container, provider);
    }

    var custom = control as CustomCheckbox;
    if (custom != null)
    {
        custom.DocumentLoaded = true;
        custom.Initialize(container);
    }

    foreach (Control subControl in control.Controls)
    {
        Initialize(subControl, container, provider);
    }
}


public interface ICustomControlWithText : ICustomControl
{
    void Initialize(DocumentContainer container, ErrorProvider provider);
    void InitializeValidations();

    string Text { get; set; }
    ErrorProvider ErrorProvider { get; set; }
    List<IValidation> Validations { get; set; }
}


public interface ICustomControl
{
    void Clear();

    FieldType FieldType { get; set; }
    bool DocumentLoaded { get; set; }
}

class CustomCheckbox : CheckBox, ICustomControl
{
     public void Initialize(DocumentContainer container)
    {
    //...
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,取决于winforms的类型控制此代码初始化控件.它以main表单开头,包含自定义控件(IControlWithText,CustomCheckbox)和默认winforms表单.我会根据控件的类型创建3个初始化器和每个方法CanInitialize,但即使这样我也不知道如何跳过那些"ifs",如果我需要将此ErrorProvider发送到方法Initialize ,我需要知道.

我非常感谢你的帮助!

Geo*_*vos 0

从第二个接口中删除初始化逻辑,只保留验证逻辑,因此您可以编写如下内容:

public interface ICustomControl
{
        void Clear();
        FieldType FieldType { get; set; }
        bool DocumentLoaded { get; set; }
        void Initialize(DocumentContainer container);
}

public interface ICustomControlWithText 
{
        string Text { get; set; }
        ErrorProvider ErrorProvider { get; set; }
        List<IValidation> Validations { get; set; }
        void Validate(ErrorProvider provider);
}



class CustomCheckbox : CheckBox, ICustomControl    {  ...  }

class CustomTextbox : TextBox, ICustomControl, ICustomControlWithText      {...}

 public static void Initialize(Control control, DocumentContainer container, ErrorProvider provider)
    {
        var custom = control as ICustomControl;

        if (control == null)
            return;

        custom.DocumentLoaded = true;
        custom.Initialize(container);

        var controlWithTextBase = control as ICustomControlWithText;
        if (controlWithTextBase != null)
            controlWithTextBase.Validate(provider);

        foreach (Control subControl in control.Controls)
            Initialize(subControl, container, provider);
    }
Run Code Online (Sandbox Code Playgroud)

当然,如果您愿意,您可以使 ICustomControlWithText “继承” ICustomControl

public interface ICustomControlWithText : ICustomControl
Run Code Online (Sandbox Code Playgroud)