2012-01-06 104 views
0

我的代碼中至少有10次不同的代碼。對我來說似乎有點臭。泛型是否可以使用?

 public void DisplayTransitInfo(TransitInfo transitInfo) 
    { 
     if (InvokeRequired) 
      EndInvoke(BeginInvoke(new MethodInvoker(() => DisplayTransitInfo(transitInfo)))); 
     else 
     { 
      var control = (from string key in _visiblePanes.Keys 
          where key == "transitInfo" 
          select _visiblePanes[key].Control).ToList(); 

      TransitInfoControl cntl = (TransitInfoControl)control[0]; 
      //TODO: Transit Info 
     } 
    } 

    public void ModifyParties(UltraTreeNode node) 
    { 
     if (InvokeRequired) 
      EndInvoke(BeginInvoke(new MethodInvoker(() => ModifyParties(node)))); 
     else 
     { 
      var control = (from string key in _visiblePanes.Keys 
          where key == "parties" 
          select _visiblePanes[key].Control).ToList(); 

      PartiesControl cntl = (PartiesControl)control[0]; 
      cntl.ModifyParties(node); 
     } 
    } 

我覺得在這種情況下可以使用泛型。我也考慮搬家:

   var control = (from string key in _visiblePanes.Keys 
          where key == "parties" 
          select _visiblePanes[key].Control).ToList(); 

它自己的函數將返回字典中的控件的實例。

此代碼是否有臭味或我只需要讓我的鼻子工作?

一如既往的感謝!

回答

3

如果您正在尋找簡化

 var control = (from string key in _visiblePanes.Keys 
         where key == "transitInfo" 
         select _visiblePanes[key].Control).ToList(); 

     TransitInfoControl cntl = (TransitInfoControl)control[0]; 

 var control = (from string key in _visiblePanes.Keys 
         where key == "parties" 
         select _visiblePanes[key].Control).ToList(); 

     PartiesControl cntl = (PartiesControl)control[0]; 

如果_visiblePanes是一本字典,這意味着它可以有沒有重複鍵,那麼你並不需要仿製藥,只是用這個來代替:

var cntl = (TransitInfoControl)_visiblePanes["transitInfo"].Control; 

var cntl = (PartiesControl)_visiblePanes["parties"].Control; 

編輯

(添加石膏對含原代碼等價)

這個建議,與吉姆·米契爾的相比,不僅是簡單的輸入和閱讀,也更接近原始代碼,因爲如果密鑰不在字典中,它會引發異常。如果原始代碼使用Linq試圖掩蓋這種可能性,則它在PartiesControl cntl = (PartiesControl)control[0];失敗。假設字典中沒有關鍵字是非例外的,那麼當然,Jim的TryGetValue解決方案更好。

要返回有關仿製藥原來的問題,有一個可能的優勢,在提取GET和鑄造邏輯到一個通用的方法:

bool TryGetCast<T>(IDictionary<string, BaseControl> dict, string key, out T value) where T : BaseControl 
{ 
    BaseControl tryGet; 
    if (dict.TryGetValue(key, out tryGet) 
    { 
     value = (T)tryGet; 
     return true; 
    } 
    value = default(T); 
    return false; 
} 

因此可以稱爲:

PartiesControl cntl; 
if (TryGetCast(_visiblePanes, "parties", out cntl)) 
{ 
    //do whatever; 
} 

但是,好處是輕微的。吉姆的解決方案再加上演員陣容沒有太大的更詳細:

BaseControl c; 
if (_visiblePanes.TryGetValue("parties", out c)) 
{ 
    var cntl = (PartiesControl)c; 
    // do whatever 
} 
3

如果你在你的應用程序中有相同的代碼10次,它肯定是重構!

爲什麼你寫

(from string key in _visiblePanes.Keys 
         where key == "parties" 
         select _visiblePanes[key].Control) 

時,你可以使用_visiblePanes["parties"](或使用TryGetValue如果你不知道鍵是否存在)?

爲什麼control是一個列表? control聽起來不像集合的名稱。

+0

是的,如果沒有別的東西把這個代碼封裝到它自己的對象中。 – 2012-01-06 17:48:36

2

我可能失去了一些東西,但在我看來,你可以擺脫整個LINQ表達的存在那裏。也就是說,該代碼:

var control = (from string key in _visiblePanes.Keys 
       where key == "parties" 
       select _visiblePanes[key].Control).ToList(); 
PartiesControl cntl = (PartiesControl)control[0]; 

如果我讀的是正確的,你枚舉密鑰的集合,即可找出所有具有鍵「當事人」的項目。但是既然你寫了_visiblePanes[key].Control,看起來好像只有其中之一。我打算假設_visiblePanesDictionary<string, BaseControl>,其中BaseControl是任何類PartiesControl和您的其他控件類型繼承。

BaseControl cntl; 
if (_visiblePanes.TryGetValue("parties", out cntl)) 
{ 
    PartiesControl pcntl = cntl as PartiesControl; 
    // do whatever 
} 
+0

您無法將'PartiesControl'傳遞給'IDictionary .TryGetValue';變量的類型必須是'BaseControl'。因此您需要添加一個強制轉換來訪問子類的任何成員。 – phoog 2012-01-06 18:48:01

+0

@phoog:很好。糾正。 – 2012-01-06 22:50:08

相關問題