2017-02-23 74 views
0

我有以下非常重複的代碼,我想簡化它,但由於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(); 
} 
+2

如果它沒有壞掉,請不要修復它。你爲什麼要簡化它?沒有什麼複雜的,如果你的客戶不能理解lambda表達式,他們不太可能理解你用它做的任何事情。 – DavidG

+0

因爲我現在有另外15-20個事件處理程序遭受同樣的問題,並希望簡化它們。 – cogumel0

+0

有代表的字典嗎?一種巨大的'switch' /'case'方法?你的客戶想要什麼? – Sinatr

回答

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

這看起來很簡單我。如果你想確保其他人能夠理解它,那麼只需評論每一行,就像我上面所說的那樣。如果這對他們來說太難了,那麼我會首先問他們在做什麼支持代碼的生意!

+0

使用'標籤'屬性和反射正是我已經想到的(查看有問題的評論),但是它很好,你把它放在一個答案。我會讓問題持續一段時間,看看是否有其他問題出現,但如果沒有,我會標記你的答案是正確的。 – cogumel0

+0

雖然我會做一個改變:我會在'Tag'屬性上使用一個字符串,以便它可以在編輯器中看到並將'(PropertyInfo)textbox.Tag;'更改爲'typeof(NetworkAdapter).GetProperty((string) textbox.Tag)'。 – cogumel0

+0

啊,你有!嗯,我想你已經知道簡潔(不重複)的代碼通常是很好的代碼,正如你已經提出的那樣。因此,只要確保它的評論很好,並且在做好工作時感到安全。 –