将C#对象更改为在运行时决定的类型

时间:2017-04-03 13:15:13

标签: c# winforms type-conversion

问题

我有一个WinForms程序,必须使用不同的连接类型(如TCP,USB等)与不同的硬件进行通信。使用连接需要使用VISA提供的一组通用操作(例如打开,读取,写入, 关)。如何将数据传递给这些函数或在使用之前或之后可能需要应用于数据的任何变换因连接类型而异。

当某些方法决定特定硬件操作需要某种类型的某种连接(由某些其他数据指定)时,连接用于连接到不同的硬件。

在未来的某个时刻,我可能想要添加更多类型的连接。

应用程序的用户可以选择和编辑其连接部分,该连接部分需要改变连接类型(即,从使用TCP变为使用USB)。更改类型意味着将使用不同的方法实现来操作物理连接。编辑我正在处理的连接时,这是类型的更改。

与每个连接相关的数据(包括类型数据)通过外部数据源保留。

到目前为止我的解决方案

我有一个抽象类Connection,其中包含一些派生类型,例如TcpUsb等,它们具有抽象类的常用方法和属性(例如AddressOpen()等)但实现方式不同,以便以正确的VISA接口格式获取不同的数据和地址格式。

应用程序首先从数据源填充List<Connection>。在此列表中是从Connection派生的类型的对象。

要向用户显示控件,以便在选择列表中的某个连接时允许更改类型,但仍然保持使用的一般化,表单具有RadioButton个控件,这些控件由使用反射的方法创建find生成每个派生类的一个对象,并将它们的名称添加到表单中,使用公共CheckedChanged事件处理程序

例如:

ConnectionIEnumerable = GetObjectsDerivedFromType<Connection>();
foreach (Connection c in ConnectionIEnumerable)
{
     var rb = new RadioButton();
     rb.Name = c.ToString() + "RadioButton";
     rb.CheckedChanged += new EventHandler(CommonEventHandler);
     form1.flowLayoutPanel1.Controls.Add(rb);
}

我被困在哪里

如何使用这个通用处理程序“知道”将当前所选对象转换为什么类型? RadioButton如何存储和传递有关应转换为相关类型的信息?

我已经考虑过以其他方式尝试此计划,但它总是回到一个要求,在某些时候需要某种if检查当前类型来转换它,或检查类型被转换为,因此引入非一般性。

我认为这样做的OOP封装方式是以某种方式将每个RadioButton关联的类型信息关联起来,并让类型本身定义如何在它们之间进行转换但是我我不确定这是正确的,还是最好的方法;使用强制替换,类型转换器,IConvertible等。这样处理程序可以使用类似(例如)下面的内容来替换List上的对象:

    currentObject.ConvertTo( (Type)( (RadioButton)sender).Tag ) );

更新

对于任何有类似窘境的人,我采取了Patrick Hoffman的答案并将类型信息保存到RadioButton.Tag,如下所示:

rb.Tag = c.GetType()

然后在处理程序中使用它:

EditedConnection = (Connection)Activator.CreateInstance((Type)((RadioButton)sender).Tag);

1 个答案:

答案 0 :(得分:2)

  

如何使用这个通用处理程序“知道”将当前所选对象转换为什么类型?

不应该知道这一点。如果您的程序完全依赖于抽象基类,那么您需要做的唯一想法是将类型实例化一次,并在整个程序中使用基类。

如果您需要构建实例,Activator.CreateInstance(Type)就是您所需要的。您可以从填充列表之前的反射中检索类型。