如何简化以下代码

时间:2017-02-23 10:12:17

标签: c# .net

我有以下非常重复的代码,我想简化,但由于NetworkAdapter对象的属性而在每个事件处理程序上都有所不同。

最好的方法是什么?理想情况下,这应该在没有lambda表达式的情况下实现,因为我这样做的客户端几乎不了解C#甚至更少的lambda,并且在完成此操作时他们会支持代码。

private void textBoxNetworkSubnetMask_TextChanged(object sender, EventArgs e)
{
    IPAddress.TryParse(textBoxNetworkSubnetMask.Text, out var ipAddress);

    ((NetworkAdapter)comboBoxNetworkCard.SelectedItem).SubnetMask = ipAddress;

    wizardPageNetworkDetails.AllowNext = ValidateNetworkDetailsPage();
}

private void textBoxNetworkGateway_TextChanged(object sender, EventArgs e)
{
    IPAddress.TryParse(textBoxNetworkGateway.Text, out var ipAddress);

    ((NetworkAdapter)comboBoxNetworkCard.SelectedItem).Gateway = ipAddress;

    wizardPageNetworkDetails.AllowNext = ValidateNetworkDetailsPage();
}

private void textBoxNetworkPrimaryDns_TextChanged(object sender, EventArgs e)
{
    IPAddress.TryParse(textBoxNetworkPrimaryDns.Text, out var ipAddress);

    ((NetworkAdapter)comboBoxNetworkCard.SelectedItem).PrimaryDns = ipAddress;

    wizardPageNetworkDetails.AllowNext = ValidateNetworkDetailsPage();
}

1 个答案:

答案 0 :(得分:2)

只需创建一个事件处理程序,并更改所有“TextChanged”事件以使用该处理程序。

即:

private void textBoxIPField_TextChanged(object sender, EventArgs e)
{
    var textBox = (Textbox)sender;
    IPAddress.TryParse(textBox.Text, out var ipAddress);

    string propertyName = "";
    switch(textBox.Name)
    {
        case textboxNetworkSubnetMask:
            propertyName = "SubnetMask";
            break;
        case textboxNetworkGateway:
            propertyName = "Gateway";
            break;
        case textboxNetworkPrimaryDns:
            propertyName = "PrimaryDns";
            break;
    }
    PropertyInfo pi = typeof(NetworkAdapter).GetProperty(propertyName);
    pi.SetValue((NetworkAdapter)comboBoxNetworkCard.SelectedItem, ipAddress);

    wizardPageNetworkDetails.AllowNext = ValidateNetworkDetailsPage();
}

一些反射减少了您在switch语句中编写的代码量。 (确保使用System.Reflection)如果您对文本框命名非常小心,我猜您可以用

替换整个开关块

propertyName = textBox.Name.Substring(14)

这会减少代码量,但在我看来会让它变得非常脆弱。一个更好的选择可能是将每个文本框的Tag值设置为PropertyInfo,它是您在构造函数中感兴趣的NetworkAdapter类的属性,然后在上面的事件处理程序中引用它以便设置财产价值。

PropertyInfo pi = ((PropertyInfo)textBox.Tag);

然后代码简化为:

//constructor
public MyFormClass()
{
    InitializeComponent();

    //each textbox has a Tag set to the property of a NetworkAdapter that it refers to
    textboxNetworkSubnetMask.Tag = "SubnetMask";
    textboxNetworkGateway.Tag = "Gateway";
    textboxNetworkPrimaryDns.Tag = "PrimaryDns";
}
....

private void textBoxIPField_TextChanged(object sender, EventArgs e)
{
    // (1) determine which textbox we are referring to...
    var textBox = (Textbox)sender;

    // (2) get the IP address that was entered in the textbox
    IPAddress.TryParse(textBox.Text, out var ipAddress);

    // (3) Get the Property of a Network adapter that needs changing.
    // The name of this property was stored in the textbox's Tag in construction.
    PropertyInfo pi = typeof(NetworkAdapter).GetProperty((string)textbox.Tag);

    // (4) Set the new value for that property for the selected NetworkAdapter
    pi.SetValue((NetworkAdapter)comboBoxNetworkCard.SelectedItem, ipAddress);

    wizardPageNetworkDetails.AllowNext = ValidateNetworkDetailsPage();
}

这看起来很简单。如果你想确保其他人能够理解它,那么只需评论每一行,就像我上面所说的那样。如果这对他们来说仍然太难了,那么我首先会质疑他们在做什么业务支持代码!