【问题标题】:How to convert to a specific type when the originating type is unknown?当原始类型未知时如何转换为特定类型?
【发布时间】:2010-12-29 12:46:13
【问题描述】:

这段代码代表了我的逻辑。显然它不起作用。请告知如何使其工作。

switch (ObjectToControl.GetType().ToString())
{
    case "DataList":
        DataList Controled = (DataList)ObjectToControl;
        break;
    case "DetailsView":
        DetailsView Controled = (DetailsView)ObjectToControl;
        break;
    case "FormView":
        FormView Controled = (FormView)ObjectToControl;
        break;
    case "ListView":
        ListView Controled = (ListView)ObjectToControl;
        break;
    default:
        GridView Controled = (GridView)ObjectToControl;
        break;
}

【问题讨论】:

  • 切换后的“受控”在做什么?
  • 以利沙的评论非常中肯。这个问题的答案在很大程度上取决于您计划在转换发生后做什么。

标签: c# .net types


【解决方案1】:

为什么要转换它?

所有这些类型都继承自 Control。只需将方法的返回值键入为 Control,然后将对象转换为 Control。

return ObjectToControl as Control;

如果在其他地方,您需要执行仅列出的一种类型可以处理的功能,那么在 that 点,在 that 方法中,检查以确保在强制转换和调用仅存在于该特定类型上的方法之前,它是正确的类型..

   if (objecttoControl is TypeToCheck)
       (objecttoControl as TypeToCheck).[MethodName](parameters); 

或者..

   TypetoCheck myObj = objecttoControl as TypeToCheck;
   if(myObj != null) myObj.[MethodName](parameters); 

当很有可能获取不是TypeToCheck 实例的对象时(如本问题所提出的场景),首选第一种方法。当您希望只有 TypeToCheck 的实例能够到达那行代码时,第二种方法会更好......

【讨论】:

    【解决方案2】:

    替换

    ObjectToControl.GetType()
    

    ObjectToControl.GetType().Name
    

    如果这就是你想要做的。

    【讨论】:

    • 直到出现CompletelyDifferent.DataList
    【解决方案3】:

    GetType().ToString() 返回完全限定的命名空间。 “ListView”将作为“System.Windows.Forms.ListView”返回。

    【讨论】:

      【解决方案4】:

      试试这个:

          object Controled = null; // Default is that we don't know what this is
          if (ObjectToControl is DataList)
              Controled = ObjectToControl as DataList;
          else if (ObjectToControl is DetailsView)
              Controled = ObjectToControl as DetailsView;
          else if (ObjectToControl is FormView)
              Controled = ObjectToControl as FormView;
          else if (ObjectToControl is ListView)
              Controled = ObjectToControl as ListView;
          else if (ObjectToControl is GridView)
              Controled = ObjectToControl as GridView;
      

      【讨论】:

        【解决方案5】:

        这样试试

        if (ObjectToControl is CheckBox){
        
            ((CheckBox)ObjectToControl).IsChecked = true;
            //Code Here
        }
        
        else if (ObjectToControl is Textbox){
        
            //Code Here
        }
        

        这将避免命名空间混淆。

        【讨论】:

          【解决方案6】:

          另一种方法是使用“is”关键字:

          if(ObjectToControl is DataList)
          {
            DataList Controled = (DataList)ObjectToControl;
            //Do something specific to your data list
          }
          else if(ObjectToControl is DetailsView)
          {
            DetailsView Controled = (DetailsView)ObjectToControl;
            //Do something specific to your details view
          }
          //etc
          

          这往往是一种代码异味,暗示您的设计存在问题,但如果您事先不知道类的类型。

          【讨论】:

          • 失败; Controledif 块之后超出范围。
          【解决方案7】:

          ObjectToControl.GetType().ToString() 将返回命名空间 + 类名。也许这就是为什么你的开关没有命中的原因。

          【讨论】:

            【解决方案8】:

            如果原始类型未知且无法发现,则无法进行有效转换。话虽如此,那绝不应该发生。

            由于ObjectToControl.GetType().ToString() 返回类的完全限定名,因此您的代码将始终按原样匹配default 大小写。

            您能否更具体地说明您的问题的性质?例如是编译时还是运行时?

            【讨论】:

              猜你喜欢
              • 2019-05-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-09-28
              相关资源
              最近更新 更多