2012-12-05 57 views
0

我可以解決這個問題,但我很好奇,爲什麼它不會工作:如何分配默認類型以創建可選的類型參數?

在,你可以創建一個程序,默認值的可選參數,例如下面的一個同樣的方式... ..

public void SomeRoutine(string Title = "Missing") 
    { 
     // Do something with Title 
    } 

....爲什麼你不能指定一個默認的類型作爲一個可選的參數?

以下示例給出了錯誤:「默認參數''類型'必須是編譯時間常量。」

public void SomeOtherRoutine(Type theType = typeof(MyClass)) 
    { 
     // Do something based on theType 
    } 

實際應用中試圖做枚舉包含底座和各種派生類的混合收集提供的選項,只返回類類型的興趣:

public IEnumerable<MyBaseClass> EnumerateWithOptions(Type optionalDerivedClass = typeof(MyBaseClass)) 
    { 
     foreach (MyBaseClass thingy in MyCustomCollection()) 
     { 
      if (thingy.GetType() == optionalDerivedClass) 
      { yield return thingy; }; 
     } 
    } 

的顯而易見的選擇是重載例程以應用默認值,如下所示,但由於不值得嘗試描述的原因,它在我的應用程序中並不理想。

public IEnumerable<MyBaseClass> EnumerateWithOptions() 
    { 
     return EnumerateWithOptions(typeof(MyBaseClass)); 
    } 
    public IEnumerable<MyBaseClass> EnumerateWithOptions(Type optionalDerivedClass) 
    { 
     foreach (MyBaseClass thingy in MyCustomCollection()) 
     { 
      if (thingy.GetType() == optionalDerivedClass) 
      { yield return thingy; }; 
     } 
    } 

任何想法爲什麼typeof(MyClass)不被認爲是一個編譯時間常量,或任何想法不同的方法?謝謝。

+0

如果你提供一個默認值時,編譯器爲您創造過載。因此,我通常避免提供默認值並使用重載方法。 – Trisped

+0

感謝您的評論。當有多個參數與默認值時,過載在邏輯上與默認值不同。我提供的示例沒有顯示它,但應用程序在EnumerateWithOptions例程中有幾個參數,每個參數都具有默認值 - 包括枚舉方向,行與列第一次掃描,子級包含,重複鍵迭代器等。試圖表達所有作爲重載的選項組合太多了。 – user1689175

回答

1

因此,你不能使用typeof或一些Type價值,你不想手動創建過載,然後再考慮提供null作爲可選參數的默認值:

IEnumerable<MyBaseClass> EnumerateWithOptions(Type optionalDerivedClass = null) 
{ 
    if (optionalDerivedClass == null) 
     return MyCustomCollection(); 

    return MyCustomCollection() 
     .Where(thingy => thingy.GetType() == optionalDerivedClass); 
} 

如果有可能爲你使用通用參數,而不是Type對象,那麼你可以通過Enumerable.OfType<T>()過濾收集:

IEnumerable<MyBaseClass> result = MyCustomCollection().OfType<YourType>(); 
+0

null的使用最接近我直接解決如何使用默認值設置類型參數的原始問題。我仍然不確定爲什麼typeof(MyClass)不被視爲編譯時間常量。謝謝lazyberezovsky,我會將其標記爲正確的答案。 – user1689175

+0

@ user1689175 typeof()不被視爲常量,因爲它是對'System.Type.GetTypeFromHandle'的方法調用。你不能使用方法調用(只發生在運行時)來設置常量。 –

0

你可以做這樣的事情

public IEnumerable<MyBaseClass> EnumerateWithOptions<T>() 
    { 
     foreach (MyBaseClass thingy in MyCustomCollection()) 
     { 
     if (thingy.GetType() == typeof(T)) 
     { yield return thingy; }; 
     } 
    } 

使用

var list = EnumerateWithOptions<MyBaseClass>(); 
var list = EnumerateWithOptions<MyDerivedClass>(); 
+0

儘管這並不直接回答我如何使用默認值指定類型參數的原始問題 - 我非常喜歡這種方法,並會嘗試實現它。感謝您的偉大建議! – user1689175

相關問題