2009-01-06 51 views
23

我遇到了FxCop warning CA1006,Microsoft.Design「DoNotNestGenericTypesInMemberSignatures」問題。具體而言,我正在設計一個ReportCollection<T>類,它繼承自ReadOnlyCollection<Report<T>>,其public構造函數將IList<Report<T>>作爲參數。FxCop警告CA1006有什麼好的解決方法嗎?

固定此警告的建議是不是非常有用:

「要修復與該規則的衝突,改變設計以刪除嵌套式的說法。」有兩種方法,我可以這麼遠看改變設計的建議:

  1. 使構造internal。這在我的情況下不起作用。構造函數必須是public,因爲此集合類需要通過程序集外部的代碼實例化。
  2. 使構造函數採取Report<T>[]而不是IList<Report<T>>。這是次優的,因爲外部代碼應該具有使用動態大小的數據結構(如List<T>)而不是固定大小數組的靈活性。

在這一點上,我放棄並壓制了這個警告。有更好的解決方案嗎?

回答

20

我同意,另一個好時機,忽略了這條規則是,當你需要說:

Func<IEnumerable<T>> 
當然

你可以使用非通用IEnumerable的,但隨後的任何類型都可以使用,只要它實現IEnumerable(非泛型)。泛型的目的(部分)是限制可授予給定類型集的類型。

我覺得這個規則很愚蠢。如果你有多個嵌套的泛型類型,只需要它。一層嵌套不僅安全。

BTW,我想了很多的LINQ功能巢的泛型類型一樣,所以如果MS做的話,我們也可以做到:)

+3

我不會對嵌套的「安全」級別設置任何限制。泛型類型應儘可能嵌套語義所需。接口對協方差和反變換支持的限制意味着期望'IDictionary >`將不能接受`IDictionary <字符串,列表>`,但是當嵌套的泛型在語義上正確時,我傾向於使用它們而不是試圖解決它們。 – supercat 2014-06-02 18:26:01

30

我會採取FxCop的警告,好像他們是來自一位非常肛門保持性同事的建議。忽略(壓制)它所暗示的一些事情是完全可以的。

+2

+1這也是一個設計警告,所以有時候這些真的可以歸類爲審美,特別是如果你沒有一個設計公共API。 – 2010-11-23 04:12:33

4

我同意,你可以忽略的

的情況下,CA1006警告
Func<IEnumerable<T>> 

您也可以通過委託簡化代碼,避免CA1006:

public delegate IEnumerable<T> ChildrenDel<T>(T parent); 

// was: GetDescendants<T>(this T item, Func< T, IEnumerable<T> > children) 

public static IEnumerable<T> GetDescendants<T>(this T item, ChildrenDel<T> children) 
{ 
    var stack = new Stack<T>(); 
    do { 
     children(item).ForEach(stack.Push); 

     if(stack.Count == 0) 
      break; 

     item = stack.Pop(); 

     yield return item; 
    } while(true); 
} 
+0

使用委託而不是`Func <>`的一個問題是,Visual Studio不會給你一個關於自定義委託在與父函數簽名相同的彈出窗口中定義的提示 - 而`Func`很直觀地推斷出lambda for。當然,這是一個IDE問題,而不是語言問題。 – Dai 2017-08-11 01:02:50

相關問題