代码之家  ›  专栏  ›  技术社区  ›  balexandre

重构:如何重构未知类型?

  •  0
  • balexandre  · 技术社区  · 15 年前

    我不知道如何使用“T”,我也从来没有很好地理解它,但我相信答案会存在于它周围的任何事物中…

    我有一个巨大的开关,它所做的一切就是将属性应用于对象并将控件添加到集合中,类似于extract>apply attribute>add,例如:

    第一开关

    foreach (AdwizaControl control in form.AdwizaControls)
    {
        Panel panel = new Panel();
        int x = 0, y = 0;
        switch (control.Type)
        {
    
            case ControlType.CheckBox:
                AdwizaCheckBox checkbox = (AdwizaCheckBox)control.AdwizaWebControl;
                x = checkbox.X;
                y = checkbox.Y;
                panel.Controls.Add(checkbox);
                break;
            case ControlType.Bevel:
                AdwizaBevel bevel = (AdwizaBevel)control.AdwizaWebControl;
                bevel.Width = bevel.W;
                bevel.Height = bevel.H;
                panel.Controls.Add(bevel);
                break;
    

    checkbox.x和checkbox.y是来自定义XML的属性,这里我们将控件设置为该大小

    第二开关 (循环访问radpageview(telerik组件)内的控件)

    foreach (RadPageView pageView in multiPage.PageViews)
    {
        int controlCount = pageView.Controls.Count;
    
        for (int i = 0; i < controlCount; i++)
        {
            if (pageView.Controls[i].GetType() == typeof(AdwizaControl))
            {
                switch (((AdwizaControl)pageView.Controls[i]).Type)
                {
    

    case ControlType.Grid:
        AdwizaGrid pageViewGrid = (AdwizaGrid)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        pageViewGrid.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewGrid.Y + increaseY, pageViewGrid.X + increaseX));
        pageView.Controls.Add(pageViewGrid);
        break;
    case ControlType.Hyperlink:
        AdwizaHyperlink pageViewHyperlink = (AdwizaHyperlink)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        pageViewHyperlink.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewHyperlink.Y + increaseY, pageViewHyperlink.X + increaseX));
        pageView.Controls.Add(pageViewHyperlink);
        break;
    case ControlType.ImageBox:
        AdwizaImageBox pageViewImageBox = (AdwizaImageBox)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        pageViewImageBox.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewImageBox.Y + increaseY, pageViewImageBox.X + increaseX));
        pageView.Controls.Add(pageViewImageBox);
        break;
    case ControlType.Label:
        AdwizaLabel pageViewlabel = (AdwizaLabel)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        pageViewlabel.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewlabel.Y + increaseY, pageViewlabel.X + increaseX));
        pageView.Controls.Add(pageViewlabel);
        break;
    case ControlType.Slavebox:
        AdwizaSlavebox pageViewSlavebox = (AdwizaSlavebox)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        pageViewSlavebox.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewSlavebox.Y + increaseY, pageViewSlavebox.X + increaseX));
    
        pageView.Controls.Add(pageViewSlavebox);
        break;
    case ControlType.Repeatbox:
        AdwizaRepeatBox pageViewrepeatbox = (AdwizaRepeatBox)((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        pageViewrepeatbox.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewrepeatbox.Y + increaseY, pageViewrepeatbox.X + increaseX));
        pageView.Controls.Add(pageViewrepeatbox);
        break;
    

    它更大,因为它必须覆盖我正在使用的所有对象…

    我怎样才能打个简单的电话?类:

    ApplyPositionAttribute(
        ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl);
    

    有没有办法简化这个?


    补充 switch语句

    3 回复  |  直到 15 年前
        1
  •  0
  •   Sergej Andrejev    15 年前

    如果adwizarepeatbox、adwizarepeatbox、adwizaslavebox和其他类没有扩展具有属性属性的单个类,那么最好搜索反射命名空间以查找答案或重写代码,以便它们扩展单个类。

    如果它们扩展单个类而不是您要查找的代码,则应该如下所示:

    private void ApplyPositionAttribute<T>(AdwizaWebControl webControl) where T : InheritedClass
    {
        /* ... */
    
        T adwizalControl = (T)webControl;
        pageViewrepeatbox.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewrepeatbox.Y + increaseY, pageViewrepeatbox.X + increaseX));
        pageView.Controls.Add(pageViewrepeatbox);
    }
    

    编辑

    如果所有ADwizaControl都扩展具有属性属性的单个类,则使用此选项。如果扩展了X和Y属性,请使用虚拟关键字重写基类声明

    AdwizaWebControl webControl = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    webControl.Attributes.Add("style", string.Format("position:absolute;top:{0}px;left:{1}px;", webControl.Y + increaseY, webControl.X + increaseX));
    pageView.Controls.Add(webControl);
    
        2
  •  0
  •   Péter Török    15 年前

    我明白所有的课程 AdwizaGrid , AdwizaHyperlink 等有 AdwizaControl 作为公共基类。我也假设 Attributes 在基类中定义。在这种情况下,您可以像这样删除大部分复制:

    AdwizaControl control;
    
    case ControlType.Grid:
        control = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        break;
    case ControlType.Hyperlink:
        control = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
        break;
    ...
    

    然后在案件发生后:

    control.Attributes.Add(
            "style", string.Format("position:absolute;top:{0}px;left:{1}px;",
            control.Y + increaseY, control.X + increaseX));
    pageView.Controls.Add(control);
    

    在此之后,您可以用某种类型的从控制类型到属性的映射来替换大交换机(我不熟悉C语言,所以我不能给您一个精确的提示,但是,在C++中,您可以使用函数或指针到成员)。

        3
  •  0
  •   empi    15 年前

    在这种情况下,您不必使用泛型。如果您的所有控件都继承自advizaWebControl,则可以这样编写:

    AdwizaWebControl webControl = ((AdwizaControl)pageView.Controls[i]).AdwizaWebControl;
    webControl.Attributes.Add("style", string.Format("position:absolute;top:{0}px;left:{1}px;", pageViewGrid.Y + increaseY, pageViewGrid.X + increaseX));
    pageView.Controls.Add(webControl);
    

    但是,如果您的类不从AdwizaWebControl泛型继承,则不会有帮助。