动态代码片段 c# visual studio

12

我正在进行一个WinForms项目,每天都有一些重复的任务。因此我想创建代码片段来帮助我,但它仅适用于固定的代码。

我希望根据控件名称和某些条件动态创建代码片段。

我希望在设计部分完成后添加代码。我像这样定义控件名称intTextboxAge。代码片段应该为所有文本框添加自动验证,使用以下定义的函数。

基于控件名称前缀(int、str、dou、dec),必须有不同的控件,例如:

public void AutoCode()
{
    int i=0;
    foreach(On all controls)
    { 
        if(controls is textbox or combobox)
        {
            if(control.text starts with int)
            {
                a[i] = Validation.ValidateInt(labelError, control.text, val => acdnt.date = val);
            }
        }
    }
}

我希望能够自动生成代码片段,库无法帮助我。

我的动机不仅仅是为了验证而生成代码,上面的例子只是展示如何实现这一点。

我希望能够自动生成主窗体中所有业务逻辑的代码,例如:

  1. 验证
  2. 为变量创建新类
  3. 在验证后对类进行数据填充
  4. 自动生成数据库函数insert和update

因为在所有上述任务中,只有变量名更改,其余业务任务保持不变。我们该如何实现呢?

自动生成类- 类将通过表单名称+"Class"创建,并且变量类型将由前3个字符确定,并命名为控件名称相同。

自动生成数据库函数insert和update- 将数据库表名命名为表单名称,列名与控件名称相同,这样就可以动态地创建插入和更新查询。

为什么我不想使用类库?因为在那种情况下,它会在运行时执行所有操作,这将在某些地方损耗我的性能。

通过这种方式,我们可以节省大量编码时间和精力。


一个具体的例子会帮助我们为您提供建议。您是指在插入代码片段之前,提示您输入动态值吗? - Sherin Mathew
3
与其编写一小段代码片段,为什么不建立一个适当方法的库呢?从多个地方调用同一段代码要比将整段代码复制到多个地方更好。最好只编写这段代码一次,然后从多个地方调用它。 - Jon Skeet
@Sascha 我需要选择开源软件,以便根据我的需求进行修改。 - Hot Cool Stud
1
你是否已经确认确实存在性能问题,还是只是猜测?目前还不清楚哪些内容可以在编译时移动... - Jon Skeet
4
所以你会有两种方法——你不必编写一个方法来执行人类所知的每个验证。 - Jon Skeet
显示剩余5条评论
3个回答

7
设计部分完成后,我想要添加代码。我会使用 intTextboxAge 这样的命名来定义控件名称。以下代码片段应该为所有文本框添加自动验证,使用下面定义的函数。
最好有自己的验证 CustomControls ,这样在设计部分完成后就不需要再添加代码了。
//Integer input CustomControl with validation label (pictured above)
public partial class intTextBox : UserControl
{
    public bool IsValid {get;set;}
    public intTextBox()
    {
        InitializeComponent();
        this.textBox1.TextChanged += this.intTextBox_TextChanged;
    }

    private void intTextBox_TextChanged(object sender, EventArgs e)
    {
        int n;
        IsValid = int.TryParse(this.textBox1.Text, out n);
        label1.Visible = !IsValid;
    }
}

根据控件名称前缀(int,str,dou,dec),必须有不同的控件。

虽然您可以使用控件名称前缀,但我建议创建自己的UserControl 通过派生基本控件并仅测试控件类型:

//Decimal input UserControl
public class decTextBox : TextBox
{
    public string Text
    {
        get {
            return this.Text;
        }
    }

    public bool IsValid()
    {
        decimal n;
        bool isDecimal = decimal.TryParse(this.Text, out n);
        return isDecimal;
    }
}

....

public Control AutoCode(Control forEgTheForm)
{
    //Tip: You may need to recursively call this function to check children controls are valid
    foreach(var ctrl in forEgTheForm.Controls) { 
        if(ctrl is TextBoxBase) {
             if(ctrl is decTextBox) {
                 decTextBox txt = ((decTextBox)ctrl);
                 //If its not a valid value then set a[i]=true/false or in this example return the control...
                 if (!txt.IsValid()) return ctrl;
             }
        }
    }
}

我想根据控件名称和一些条件动态创建代码片段。

如果要创建代码片段,请按控件类型而不是控件名称前缀来执行,这样您就不需要它们是动态的了。

...


更优秀的解决方案是不需要编写任何片段或验证代码。我建议使用正确类型的控件来实现。文本框适用于字符串,但对于整数、小数和双精度浮点数,最好使用 NumericUpDown 控件。这样用户直觉地知道它们需要输入数字(并且无法输入字母数字字符)。在设置了几个 NumericUpDown 控件属性后(无论是设计时还是运行时),您将不需要编写验证代码:

enter image description here


我不确定您遇到的性能降低的原因是什么?但我建议将控件绑定到具有所有业务逻辑的类库中,以便进行单元测试。对于前端验证,只需像上面所示那样验证输入是否正确即可。


很高兴聊聊这个答案。我知道它不是你要求的“动态片段”,但它太长了,不适合作为评论,并且提出了不需要编写片段的建议...干杯 - Jeremy Thompson
我查看了您的更新,并认为这个QA正在变成一个变色龙问题。你对我关于采用面向对象编程(OOP)、避免重复代码(DRY)和单一职责原则(SOLID)方法的建议有什么想法? - Jeremy Thompson
之前问题描述不够详细,非常抱歉。 - Hot Cool Stud

1
你可以尝试基于脚本的代码生成器,比如CodeSmith(也有免费的)。
你可以编写基于你定义的变量(也可以基于数据库项目)的脚本,然后生成代码。
生成代码是一个不错的方法,因为它节省时间,同时也标准化了代码。

1

我认为你可以使用System.Reflection命名空间结合System.CodeDom命名空间来实现你想要的功能。

你可以使用System.Reflection命名空间中的类和System.Type类来发现程序集名称、命名空间、属性、方法、基类以及其他与类或变量相关的元数据。 然后,你可以使用这些从起始/源类(例如,你的窗体类)获取的元数据,利用CodeDOM生成目标类(业务和数据类)的代码。

请参考这个msdn链接How to: Create a Class using CodeDOM作为起点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接