C# 如何简化以下代码

C# 如何简化以下代码,c#,.net,C#,.net,我有以下非常重复的代码,我想对其进行简化,但由于NetworkAdapter对象的属性不同,每个事件处理程序的属性都不相同,因此很难实现 最好的方法是什么?理想情况下,这应该在没有lambda表达式的情况下实现,因为我为之做这项工作的客户机对C#的了解很少,甚至对lambda的了解更少,完成这项工作后,他们将支持代码 private void textBoxNetworkSubnetMask_TextChanged(object sender, EventArgs e) { IPAddr

我有以下非常重复的代码,我想对其进行简化,但由于
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();
}

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

即:

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

propertyName=textBox.Name.Substring(14)

这将减少代码的数量,但在我看来,它相当脆弱。更好的选择可能是将每个文本框的
标记
值设置为PropertyInfo,这是您在构造函数中感兴趣的NetworkAdapter类上的属性,然后仅参考上面的事件处理程序中的属性即可设置属性值

ie
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();
}

在我看来这很简单。如果你想确保其他人能理解它,那么只需评论每一行,就像我上面所说的。如果这对他们来说还是太难了,那么我会质疑他们在做什么生意来支持代码

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

即:

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

propertyName=textBox.Name.Substring(14)

这将减少代码的数量,但在我看来,它相当脆弱。更好的选择可能是将每个文本框的
标记
值设置为PropertyInfo,这是您在构造函数中感兴趣的NetworkAdapter类上的属性,然后仅参考上面的事件处理程序中的属性即可设置属性值

ie
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();
}


在我看来这很简单。如果你想确保其他人能理解它,那么只需评论每一行,就像我上面所说的。如果这对他们来说还是太难了,那么我会质疑他们在做什么生意来支持代码

如果它没有坏,就不要修理它。你为什么要简化它?这并不复杂,如果你的客户不能理解lambdas,他们就不太可能理解你对它所做的任何其他事情。因为我还有另外15-20个事件处理程序,它们现在面临着完全相同的问题,我想将它们全部简化。也许有一个包含委托的字典?在一种方法中有一个巨大的
开关
/
案例
?你的客户在干什么?我思想开放,包括lambdas,但在实施之前需要得到他们的批准,这就是为什么我尽量避开他们的原因。现在我想到的是将TextBox的标记设置为要设置的属性,然后使用反射设置属性。我不太确定这会比lambdas好多少,但是…我投票结束这个问题,因为这个代码正在运行,它要求进行代码审查。询问codereview.stackexchange.com如果它没有损坏,就不要修复它。你为什么要简化它?这并不复杂,如果你的客户不能理解lambdas,他们就不太可能理解你对它所做的任何其他事情。因为我还有另外15-20个事件处理程序,它们现在面临着完全相同的问题,我想将它们全部简化。也许有一个包含委托的字典?在一种方法中有一个巨大的
开关
/
案例
?你的客户在干什么?我思想开放,包括lambdas,但在实施之前需要得到他们的批准,这就是为什么我尽量避开他们的原因。现在我想到的是将TextBox的标记设置为要设置的属性,然后使用反射设置属性。我不太确定这会比lambdas好多少,但是…我投票结束这个问题,因为这个代码正在运行,它要求进行代码审查。问codereview.stackexchange.com使用
标记
属性和反射正是我已经想到的(看看有问题的评论),但是你把它放在一个答案中就太好了。我会把这个问题留一段时间,看看是否还有其他问题,但如果没有,我会标记你的答案是正确的。不过,我会做一个更改:我会在
标记上使用一个字符串,以便它在编辑器中可见,然后更改
(PropertyInfo)textbox.Tag
typeof(NetworkAdapter).GetProperty((string)textbox.Tag)
。啊,是的,你有!我想您已经知道简洁(不重复)的代码通常是好代码,正如您所建议的。因此,只需确保其评论良好,并且在出色完成的工作中感到安全。@cogumel0-是的,这对我来说似乎是一个合理的更改,已经更改了应答中的代码使用
标记
属性和反射正是我已经想到的(查看有问题的评论),但是您将其放入一个答案中,这很好。我会把这个问题留一段时间,看看是否还有其他问题,但如果没有,我会标记你的答案是正确的。不过我会做一个更改:我会在
标记上使用一个字符串,这样它就可以从编辑器中看到