Val*_*ale 5 c# .net-4.0 switch-statement
我有一个大的switch语句,我根据XElement的输入值创建UIElements:
public static UIElement CreateElement(XElement element) {
var name = element.Attribute("Name").Value;
var text = element.Attribute("Value").Value;
var width = Convert.ToDouble(element.Attribute("Width").Value);
var height = Convert.ToDouble(element.Attribute("Height").Value);
//...
switch (element.Attribute("Type").Value) {
case "System.Windows.Forms.Label":
return new System.Windows.Controls.Label() {
Name = name,
Content = text,
Width = width,
Height = height
};
case "System.Windows.Forms.Button":
return new System.Windows.Controls.Button() {
Name = name,
Content = text,
Width = width,
Height = height
};
//...
default:
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在创建这样的很多控件,正如你所看到的,重复过多.
有没有办法避免这种重复?提前感谢您的想法.
您可以创建一个执行创建的泛型函数:
private static Create<T>(string name, string text, double width, double height) where T: Control, new()
{
return new T { Name = name, Content = text, Width = width, Height = height }
}
Run Code Online (Sandbox Code Playgroud)
您的交换机将变为:
switch (element.Attribute("Type").Value) {
case "System.Windows.Forms.Label" : return Create<System.Windows.Forms.Label>(name, text, width, height);
etc.
}
Run Code Online (Sandbox Code Playgroud)
你也可以调整它来传递XElement,无论你喜欢什么.
如果Type属性始终是您想要的System.Type的名称,那么您可以这样做
Control ctrl = (Control) Activator.CreateInstance(Type.GetType(element.Attribute("Type").Value));
ctrl.Name = name;
etc.
Run Code Online (Sandbox Code Playgroud)
如果属性值与所需类型之间存在一对一映射,则可以使用映射声明只读静态字段:
private static readonly uiTypeMapping = new Dictionary<string,Type> {
{ "System.Windows.Forms.Label", typeof(System.Windows.Controls.Label) },
{ "System.Windows.Forms.Button", typeof(System.Windows.Controls.Button) },
{ etc. }
};
Run Code Online (Sandbox Code Playgroud)
并使用
UIElement elem = (UIElement) Activator.CreateInstance(uiTypeMapping[element.Attribute("Type").Value]);
etc.
Run Code Online (Sandbox Code Playgroud)
像这样的东西可以工作...... :)
var controlCreators = new Dictionary<string, Func<ContentControl>>
{
{"System.Windows.Forms.Label", () => new Label()},
{"System.Windows.Forms.Button", () => new Button()}
};
Func<ContentControl> createControl;
if (!controlCreators.TryGetValue(element.Attribute("Type").Value, out createControl))
{
return null;
}
var control = createControl();
control.Name = name;
control.Content = text;
control.Width = width;
control.Height = height;
return control;
Run Code Online (Sandbox Code Playgroud)