2013-02-09 35 views
2

我發現自己使用通用的運行時類型識別模式,特別是在編寫處理不同類型控件的代碼時。下面是模式:簡化的方法來做C#運行時類型標識,避免NULL檢查?

if (ctrl is ControlTypeEtc) 
    (ctrl as ControlTypeEtc).SomeMethod(); 

我這樣做是爲了避免做的情況下,一個NULL檢查運算符返回NULL。有沒有辦法簡化這到一個單一的操作?

+0

使用帶空檢查的'as'就像您將會得到的那樣精簡。 – 2013-02-09 21:09:19

+0

請參閱我的建議,使用預處理器: – John 2013-02-09 21:13:03

回答

4

無法在單個操作中執行此操作。

但是,使用as和檢查null更便宜,因爲在代碼示例中只有一個情況而不是兩個情況。

+0

請記住,這比您粘貼的原始代碼片段更優越,不僅因爲它執行了一次投射,而且還因爲它處理的情況是'ctrl'是一種派生'ControlTypeEtc' – Ameen 2013-02-09 21:13:26

1

我將它寫成:

ControlTypeEtc ctrl2 = ctrl as ControlTypeEtc; 
if (ctrl2 != null) 
    ctrl2.SomeMethod(); 

這避免了雙重檢查(可能被優化成一個,但我不知道)。

另一種方式:

try 
{ 
    ControlTypeEtc ctrl2 = (ControlTypeEtc)ctrl; 
    ctrl2.SomeMethod(); 
} 
catch (InvalidCastException e) 
{ 
} 
1

底線是,「大畫面」你應該知道,如果你的實例爲null,你繼續對編碼之前。實際上沒有理由在該步驟中找到捷徑。這就是說,如果你使用的是C#3或更好的版本,你可以使用擴展方法來隱藏你的代碼主邏輯中的這個細節。參見下面的示例'SomeType'和'SomeMethod',然後是一個名爲'SomeMethodSafe'的擴展方法。您可以在無引用的情況下調用'SomeMethodSafe'。

不要在家裏嘗試。

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      SomeType s = null; 
      //s = new SomeType(); 
      // uncomment me to try it with an instance 

      s.SomeMethodSafe(); 

      Console.WriteLine("Done"); 
      Console.ReadLine(); 
     } 
    } 

    public class SomeType 
    { 
     public void SomeMethod() 
     { 
      Console.WriteLine("Success!"); 
     } 
    } 

    public static class SampleExtensions 
    { 
     public static void SomeMethodSafe(this SomeType t) 
     { 
      if (t != null) 
      { 
       t.SomeMethod(); 
      } 
     } 
    } 
}