【问题标题】:C# loading specific class based on user choiceC#根据用户选择加载特定类
【发布时间】:2021-07-05 21:17:58
【问题描述】:

所以我是软件开发的初学者,在家中练习 C#。

我正在处理一个项目,并且已经到了不确定如何编写功能的地步。

想象一下,在我的解决方案中,我有一个带有下拉菜单的 winform UI。在该下拉列表中,用户可以做出选择并单击按钮来运行程序。根据用户选择的内容,它应该初始化选择的类/对象。

因此下拉菜单将包含以下选项;运行选项一,运行选项二。如果在下拉列表中选择了 runOptionTwo,则单击按钮后,它将执行以下操作: runOptionOne runoptionone = new runOptionOne(); runoptionone.Doaction();

我不想对下拉列表进行字符串检查,因为这将是 if 语句的负载。

是否有根据用户选择初始化特定类的技术或方法。

【问题讨论】:

  • 使用反射。您可以使用类名作为字符串并创建实例和调用方法。
  • @AmitVerma:所以用户会看到内部类名?不...
  • “使用反射。” - 为什么?有完全合适的模式,不需要反射。在这里,它甚至没有让任何事情变得更简单!
  • Dictionary 似乎是个不错的选择。
  • 不要在这里使用反射——这就像用炸弹在你的花园里挖出一株植物。

标签: c# class oop user-interface


【解决方案1】:

Combobox.Items 接受对象。为了显示,将使用他们的ToString() 方法。

这使得通过SelectedItem 直接访问对象成为可能。只要它们共享一个公共接口,就很容易在它们上调用方法。

private void button1_Click(object sender, EventArgs e)
{
    var obj = (Interface) comboBox1.SelectedItem;
    obj.DoSomething();
}

其他类:

internal interface Interface
{
    void DoSomething();
}

class Class1:Interface
{
    public void DoSomething() { }
    public override string ToString() => "Option 1"; // TODO: make translatable via resource
}

class Class2:Interface
{
    public void DoSomething() { }
    public override string ToString() => "Option 2";  // TODO: make translatable via resource
}

和初始化一样

private void Form1_Load(object sender, EventArgs e)
{
    comboBox1.Items.Add(new Class1());
    comboBox1.Items.Add(new Class2());
}

我不太喜欢这种方法,因为我认为ToString() 方法是相当面向开发人员的。

恕我直言,更好的方法是使用一个字典,其中显示字符串作为键,对象作为值。这样,您还可以摆脱 if 语句并降低圈复杂度:

private readonly IDictionary<string, Interface> _displayItems = new Dictionary<string, Interface>
{
    {"Option 1", new Class1()},
    {"Option 2", new Class2()}
};

private void Form1_Load(object sender, EventArgs e)
{
    foreach (var item in _displayItems)
    {
        comboBox1.Items.Add(item.Key);
    }
}

private void button1_Click(object sender, EventArgs e)
{
    var key = (string) comboBox1.SelectedItem;
    _displayItems[key].DoSomething();
}

【讨论】:

  • @OP 如果你真的需要创建新的实例,你也可以把Func&lt;Interface&gt;作为字典值:dotnetfiddle.net/8jF5Gk,这样你就有了一个简单的“工厂函数”形式。
  • 我唯一的问题(除非我错了),它看起来是在加载 {"Option 2", new Class2()} 如果这是如此一来,软件不是在制造大量甚至可能不会使用的对象吗?
  • @tryingOutcoding:这有关系吗?这些物体有多大?记住:过早优化...
  • 只有在类易于构建的情况下,您仍然可以存储类型信息。
  • 基本上,制作大对象的唯一方法是让它们容纳大数组、大字符串或大的原生对象(例如位图图像)。其他一切通常都很小。 is possible to figure out 有一个很好的调试器,但这可能超出了你目前的知识水平。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2015-10-13
  • 1970-01-01
  • 2023-03-18
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多