【问题标题】:casting object using name使用名称铸造对象
【发布时间】:2014-10-21 01:27:24
【问题描述】:

我需要使用文字字符串名称将不同的对象转换为不同的类型。一些示例代码:

string controlName = "Control";
string stringName = "string";
string panelName = "Panel";

var x = Panel();

((Control)x).Name = "SomeName";

上面的代码当然可以,但不是这一行

 ((Control)x).Name = "Normal";

如何使用线路

((controlName)x).Name = "Awesome";

我希望这是有道理的,但如果我需要进一步解释,我可以尝试。

我正在创建一系列在 xml 模式中定义的问题。问题会有所不同,例如 1. 这是什么时候发生的。 2 为什么会这样。 3.这是什么类型(type 1,type 2, type3)

所有这些都由一个基本控件读取。 1 需要答案控件作为日期时间选择器,2 需要文本框,3 需要组合框。

我会订阅文本框的 textchange 事件、datetimepicker 的值更改事件和组合框的 selectedindexchange 事件。

这过于简单化了,我实际上在做的是控制和创建事件。

我现在处理它的方式是一个巨大的案例陈述。我想知道是否有更简单的方法可以将控件转换为 xml 文档中定义的类型(字符串值)

编辑*

要求的代码

namespace ScriptControl
{
 public partial class ScriptItem
 {
    public FollowupEvent ActiveEvent{get;set;}

    public event EventHandler AnswerChanged;

    #region Constructors

    public ScriptItem()
    {
    }

    public ScriptItem(DataRow row)
    {
    }

    public ScriptItem(XElement xelem,FollowupEvent activeEvent,int instanceID)
    {
        ActiveEvent = activeEvent;

        InstanceID = instanceID;

        try
        {
            Question = xelem.Elements("Text").First().Value.ToString();
            AnswerType = xelem.Elements("Type").First().Value.ToString();
            ControlType = xelem.Elements("Control").First().Attribute("Type").Value.ToString();
            ActivityID = Convert.ToInt32(xelem.Attribute("ID").Value.ToString());
            ScriptItemType = xelem.Elements("ScriptItemType").First().Value.ToString();
            ScriptItemQuestionType = xelem.Elements("QuestionType").First().Value.ToString();
            InputControl = ConfigureInputControl(xelem.Elements("Control").First().Attribute("Type").Value.ToString());
            QuestionControl = ConfigureQuestionControl(xelem.Elements("Control").First().Attribute("Type").Value.ToString());
            Prompt = xelem.Elements("Prompt").First().Value.ToString();
        }
        catch { }
    }
    #endregion

    #region Public Properties

    public string Prompt { get; set; }

    public Panel QuestionPanel = new Panel();

    public int ActivityID { get; set; }

    public string Question { get; set; }

    public string AnswerType { get; set; }

    public object Result { get; set; }

    public Control InputControl { get; set; }

    public string ControlType { get; set; }

    public Control QuestionControl { get; set; }

    public string ScriptItemType { get; set; }

    public string ScriptItemQuestionType { get; set; }

    public int InstanceID { get; set; }

    public ScriptControl.Entities.ScriptControlBase ScriptBaseControl { get; set; }

    #endregion

    public Control ConfigureInputControl(string controlType)
    {
        switch (controlType)
                {
                    case "Checkbox":
                    InputControl = new CheckBox();
                    break;

                    case "BooleanQuestion":
                    InputControl = new BooleanQuestion();
                    ((BooleanQuestion)InputControl).AnswerChanged += ScriptItem_AnswerChanged;
                    ((BooleanQuestion)InputControl).SetQuestion(Question);
                    break;

                    case "TextBox":
                    InputControl = new TextBox();
                    ((TextBox)InputControl).KeyDown += ScriptItem_AnswerChanged;
                    break;

                    case "RadioButton":
                    InputControl = new RadioButton();
                    break;

                    case "DropDown":
                    InputControl = new RadioButton();
                    break;

                    case "DateTimePicker":
                    InputControl = new DateTimePicker();
                    ((DateTimePicker)InputControl).KeyDown += ScriptItem_AnswerChanged;
                    break;

                   case ".CustomControls.SmartParts.CauseForRepair":
                   case".CustomControls.SmartParts.Airlines":
                   case ".CustomControls.SmartParts.DREntry":
                        InputControl = GetUIControl();
                        ((FN_ControlBase)InputControl).PropertyChanged += ScriptItem_AnswerChanged;
                       break;
    }
        return InputControl;
    }

    private void ScriptItem_AnswerChanged(object sender, EventArgs e)
    {
        Dictionary<string, object> workFlowParams = new Dictionary<string, object>();

        switch (ControlType)
        {
            case "BooleanQuestion":
                Control x = ((Control)sender).Parent.Parent.Parent;

                Result = ((BooleanQuestion)x).Answer;

                workFlowParams.Add("QuestionID",Activity);
                workFlowParams.Add("InstanceID", InstanceID);
                workFlowParams.Add("Result",Result);
            break;

            case "TextBox":
                if (((KeyEventArgs)e).KeyValue == 13)
                {
                    Result = ((TextBox)sender).Text;

                    workFlowParams.Add("QuestionID", Activity);
                    workFlowParams.Add("InstanceID", InstanceID);
                    workFlowParams.Add("Result", Result);
                }
                break;

            case "DateTimePicker":
                if (((KeyEventArgs)e).KeyValue == 13)
                {
                    Result = ((DateTimePicker)sender).Text;

                    workFlowParams.Add("QuestionID", Activity);
                    workFlowParams.Add("InstanceID", InstanceID);
                    workFlowParams.Add("Result", Result);
                }
                break;

            case ".CustomControls.SmartParts.Airlines":
            case ".CustomControls.SmartParts.CauseForRepairUI":
            case ".CustomControls.SmartParts.CancelCallUI":
            case ".CustomControls.SmartParts.CostCenter":
            case ".CustomControls.SmartParts.ReadyToBill":
            case ".CustomControls.SmartParts.TemporaryFix":
            case ".CustomControls.SmartParts.BrakeRepairFollowup":
            case ".CustomControls.SmartParts.DREntry":
            default:
                if (((PropertyChangedEventArgs)e).PropertyName == "WorkComplete" & Convert.ToBoolean(((.CustomControls.FN_ControlBase)sender).GetPropertyValue("WorkComplete")) == true)
                {
                    foreach (var propty in ((.CustomControls.FN_ControlBase)sender).GetType().GetProperties())
                    {
                        if (ActiveEvent.HasProperty(propty.Name) & propty.Name != "EventID")
                        {
                            ActiveEvent.SetPropertyValue(propty.Name, ((Control)sender).GetPropertyValue(propty.Name));
                        }
                    }
                }

                workFlowParams.Add("QuestionID", Activity);
                workFlowParams.Add("InstanceID", InstanceID);
                workFlowParams.Add("Result", ActiveEvent);
                break;
        }

        AnswerChanged(workFlowParams, e);
    }

    public Control ConfigureQuestionControl(string controlType)
    {
        switch (controlType)
        {
            case "BooleanQuestion":
                ((BooleanQuestion)InputControl).SetQuestion(Question);
                break;

            case "TextBox":
                QuestionControl = new Label { Visible = true, Location = new Point(0, 0), Text = Question};
                break;

            case "DateTimePicker":
                QuestionControl = new Label { Visible = true, Location = new Point(0, 0), Text = Question};
                break;
        }

        return QuestionControl;
    }

    public Control ConfigureControl()
    {
        var height = 0;
        var width = 0;

        ScriptBaseControl = new ScriptControl.Entities.ScriptControlBase();

        if (InputControl is BooleanQuestion || ScriptItemType == "Control")
        {
            InputControl = ConfigureInputControl(ControlType);

            ScriptBaseControl.AddControl(InputControl);

            ScriptBaseControl.SetPrompt(Prompt);

            foreach (Control c in ScriptBaseControl.FilterControls(ctl => !(ctl is Panel) && !(ctl is FlowLayoutPanel) && !(ctl is GroupBox) && !(ctl is ScriptControlBase)))
            {
                height = height + c.Height;
                if (c.Width > width)
                {
                    width = c.Width;
                }
            }

            ScriptBaseControl.Size = new Size(width, height);
        }
        else
        {
            FlowLayoutPanel x = new FlowLayoutPanel();

            x.Controls.Add(QuestionControl);

            x.Controls.Add(InputControl);

            foreach (Control c in ScriptBaseControl.FilterControls(ctl => !(ctl is Panel) && !(ctl is FlowLayoutPanel) && !(ctl is GroupBox) && !(ctl is ScriptControlBase)))
            {
                height = height + c.Height;
                if (c.Width > width)
                {
                    width = c.Width;
                }
            }

            x.Size = new Size(width, height);

            ScriptBaseControl.Size = x.Size;

            ScriptBaseControl.AddControl(x);

            ScriptBaseControl.SetPrompt(Prompt);
        }
        return ScriptBaseControl;
    }

    private Control GetUIControl()
    { 
        Control uiControl = new Control(); 

        switch (ControlType)
          {
              case ".CustomControls.SmartParts.Air":
                  uiControl = new .CustomControls.SmartParts.Airlines(ActiveEvent.EventID) { ExternalSave = true};
               break;

            case ".CustomControls.SmartParts.CauseFor":
               uiControl = new .CustomControls.SmartParts.CauseForRepairUI() { ExternalSave = true };
                break;

            case ".CustomControls.SmartParts.Cancel":
                uiControl = new .CustomControls.SmartParts.CancelCallUI() { ExternalSave = true,EventID = ActiveEvent.EventID };
                break;

            case ".CustomControls.SmartParts.Cost":
                uiControl = new .CustomControls.SmartParts.CostCenter() { ExternalSave = true};
                break;

            case ".CustomControls.SmartParts.ReadyTo":
                uiControl = new .CustomControls.SmartParts.ReadyToBill(ActiveEvent.EventID) { ExternalSave = true, EventID = ActiveEvent.EventID };
                break;

            case ".CustomControls.SmartParts.Temporary":
                uiControl = new .CustomControls.SmartParts.TemporaryFix() { ExternalSave = true};
                break;

            case ".CustomControls.SmartParts.RepairFollowup":
                uiControl = new .CustomControls.SmartParts.BrakeRepairFollowup() { ExternalSave = true, EventID = ActiveEvent.EventID};
                break;

            case ".CustomControls.SmartParts.Entry":
                uiControl = new .CustomControls.SmartParts.DREntry() { ExternalSave = true };
                break;
        }

        return uiControl;
    }
}
}

【问题讨论】:

  • 您是否尝试将变量转换为名称在另一个字符串变量中动态设置的类?你为什么需要那个?可能有一种更简单的方法来实现您真正想要做的事情。
  • 不,你不能那样做。
  • 请注意,您可以从该字符串中获得的只是一个 Type 对象,并且您不能像在副本中讨论的那样从中进行转换。
  • ...并且您不需要转换,因为类型是推断出来的。
  • 您正在尝试做的事情不称为强制转换。您正在尝试访问名为 NamePropertyControlName。这被称为Reflection,它的 $%&* 非常痛苦。或者,您可以使用duck-typing,这可以通过转换为dynamic 类型来完成。但是,如果对象实现了多个 Name 属性,这将无济于事。

标签: c# casting object-type


【解决方案1】:

您不能这样做,因为C# 是一种静态类型 语言。您要转换的类型应该在编译时知道,以便编译器可以在其余代码中将x 视为Control(或其他)。如果您可以这样做:

((controlName)x).Name = "Awesome";

直到运行时才知道controlName的值是什么,或者它是否是一个有效的类型名。所以x的类型不能在编译时确定,这违反了类型安全。

C# 中静态类型的唯一例外是dynamic 功能,它允许您将变量声明为dynamic 并绕过编译时检查。您可以执行任何操作并访问dynamic 的任何成员编译时变量不会出现任何错误。但是如果您访问不存在的成员,您将在运行时获得RuntimeBinderException

这在某些情况下很有用,例如您可以创建一个以string 类型名称作为参数的方法,使用Type.GetType 方法获取类型并使用Convert.ChangeType 方法更改对象的类型,以及将结果分配给dynamic 变量。这样你就可以对你的 dynamic 对象执行任何操作,但你应该小心。顺便说一句,即使这是可能的,它也不是一个可取的方式。

【讨论】:

  • 咳咳...C#3 是一种静态类型的语言。从 C#4 开始,可能会被用作鸭式语言。
  • 谈c#时很少看到can't这个词
  • @CalvinSmith 在 C# 中有很多你不能做的事情。在这种情况下有一个解决方法(使用dynamic);但提供的语法永远不会有效。
  • @BradleyDotNET 我从来没有想过要问上面的语法是否有效。显然不是。我用一个例子来阐明我的意图,如果可能的话。
  • @CalvinSmith 我阅读了您的编辑,但仍然不明白您要完成什么。也许你应该向我们展示你的巨大的案例陈述,这样我们至少可以知道你的意图是什么
猜你喜欢
  • 2018-05-28
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 2018-05-12
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多