Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以要一种“a”型的吗;“类”;在C#中?_C#_Casting - Fatal编程技术网

我可以要一种“a”型的吗;“类”;在C#中?

我可以要一种“a”型的吗;“类”;在C#中?,c#,casting,C#,Casting,我想知道是否有可能做点什么。我有一个函数,可以读取xml文件,并根据文件内容向表单添加控件。这样的xml节点将创建它: <Button Top="300" Left="100">Automatic</Button> 但是,当我想使用更多类型的控件时,我需要不断添加开关盒。我可以做一些事情,只需要文本和添加该类型的控件吗?如果有任何反馈,我将不胜感激 谢谢 如果您控制XML文件的内容,则是。您可以使用: string fullNameSpace = "System.Win

我想知道是否有可能做点什么。我有一个函数,可以读取xml文件,并根据文件内容向表单添加控件。这样的xml节点将创建它:

<Button Top="300" Left="100">Automatic</Button>
但是,当我想使用更多类型的控件时,我需要不断添加开关盒。我可以做一些事情,只需要文本和添加该类型的控件吗?如果有任何反馈,我将不胜感激


谢谢

如果您控制XML文件的内容,则是。您可以使用:

string fullNameSpace = "System.Windows.Controls.";
Type controlType = Type.GetType( fullNameSpace + xmlchild.Name );
if( controlType != null )
{
  // get default constructor...
  ConstructorInfo ctor = controlType.GetConstructor(Type.EmptyTypes);
  object control = ctor.Invoke(null);
}
您还可以使用
Activator
类稍微清理一下:

object control = Activator.CreateInstance( "System.Windows.Presentation", 
                                           xmlchild.Name );

或者,如果可以创建有效的XAML文件,则可以使用XamlReader还原控件树。

您可以使用某种约定来保存一些代码。基本上,使用反射创建所需控件的实例,从XML传入代码。比如:

Activator.CreateInstance(xmlchild.Name, ...)

只要填入正确的位,很多代码就会消失。

听起来你在寻找类似泛型的东西

您可以执行以下操作:

public static class ControlFactory
{
    public static T CreateControl<T>() where T : Type, new()
    {
        return new T();
    }
}
公共静态类控件工厂
{
公共静态T CreateControl(),其中T:Type,new()
{
返回新的T();
}
}

我还没有测试这段代码,所以我将在测试时对其进行更新。

首先查看Activator类。然后,您可以将控件的类型名称存储为xml文件中的属性,并使用Activator类根据存储在当前xml元素的属性中的值(type=“fullTypeName”)创建实例


进一步,如果涉及到属性,可以考虑反射来基于属性名称设置已创建实例上的属性。(即,您有一个使用Activator类创建的控件实例,并将xml中Top属性的值分配给创建实例的Top属性,您可以使用反射获取/设置该属性).

可以像其他人描述的那样使用反射直接从其名称构造控件。但是,这种设计相当脆弱,如果XML文件是公开可见的,也可能会引起安全问题,因为可以在运行时根据文件中的文本构造任意控件类型。这可能不是r您的特定应用程序


我更喜欢使用
字典
的设计,其中您有注册回调的代码,该回调为每个名称创建控件。这给了您一些额外的灵活性(您可以动态交换控件构造方法或组合来自多个源的可用控件),并且看起来更干净(开关被几个“register”调用替换,实际构造被分解成单独的方法或(在简单的情况下)作为lambda表达式)。如果您将应用程序中的文本框替换为MyImprovedTextBox,并希望以前的配置文件使用改进的版本,这也允许向后兼容。

例如,您可以将类称为“MyXml*”其中*是按钮、标签等,并使用反射。如果您使用WPF,您可以使用XamlReader/Writer类+1:感谢您教我Type.EmptyTypes(这也是一个很好的答案,但只能向上投票一次)+1尽管上面的代码可以工作,但一个问题是类型名称必须正确,这样开发人员就不会/无法不检查控件的名称。最后会有一个类似开关或if/else块的错误检查方法。@Paul-或一个漂亮的大
try…catch(异常)
…好的,可能是一个较小的,具有更具体的异常类型,但您不必提前检查它。
public static class ControlFactory
{
    public static T CreateControl<T>() where T : Type, new()
    {
        return new T();
    }
}