.NET(C#): 將IGrouping轉換成IGrouping

來源:互聯網
上載者:User

我開始奢望使用內建方法快速解決這個問題,後來發現不太可能。首先無法使用C# 4.0的介面協變支援,因為協變只針對參考型別,而TKey和TElement的類型可能是實值型別的。其次整個架構對IGrouping沒有提供任何直接的輔助方法。那麼將就像將IGrouping<TKey, TElement>轉換成IGrouping<object, object>就如同將IEnumerable<int>轉換成IEnumerable<object>,看似轉換是隱式的,但卻必須加入一些轉換邏輯,如下:

IEnumerable<int> intData = Enumerable.Range(1, 10);

IEnumerable<object> objData = intData.Cast<object>();

 

當然IGrouping<TKey, TElement>並沒有IEnumerable那麼簡單,它有兩個泛型參數,同時本身又繼承IEnumerable<TElement>。因此需要寫一個輔助類型,該類型當然必須繼承IGrouping<object, object>。同時支援從IGrouping<TKey, TElement>和Object對象的建立,後者使用反射來擷取成員值。

 

範例程式碼:

//將1-10按照除3的餘數來分組

IEnumerable<IGrouping<int, int>> data = Enumerable.Range(1, 10).GroupBy(i => i % 3);

 

foreach (IGrouping<int, int> group in data)

{

    //通過輔助類型將IGrouping<int, int>轉換成IGrouping<object, object>

    IGrouping<object, object> converted = IGroupingWrapper.Create(group);

 

    //輸出資料

    Console.WriteLine("除以3餘{0}", converted.Key);

    foreach (object obj in converted)

        Console.WriteLine(obj);

}

 

將會輸出:

除以3餘1

1

4

7

10

除以3餘2

2

5

8

除以3餘0

3

6

9

 

IGroupingWrapper類型代碼:

class IGroupingWrapper : IGrouping<object, object>

{

    object key;

    IEnumerable<object> collec;

 

    IGroupingWrapper(object key, IEnumerable<object> collec)

    {

        this.key = key;

        this.collec = collec;

    }

 

    #region IGrouping<object, object> 成員

 

    public object Key

    {

        get { return key; }

    }

 

    public IEnumerator<object> GetEnumerator()

    {

        return collec.GetEnumerator();

    }

 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

    {

        return GetEnumerator();

    }

 

    #endregion

 

    //通過IGrouping<TKey, TElement>建立IGrouping<object, object>

    public static IGroupingWrapper Create<TKey, TElement>(IGrouping<TKey, TElement> igroup)

    {

        if (igroup == null)

            throw new ArgumentNullException("igroup");

 

        return new IGroupingWrapper(igroup.Key, igroup.Cast<object>());

    }

 

    //通過object建立IGrouping<object, object>

    public static IGroupingWrapper Create(object obj)

    {

        if (obj == null)

            throw new ArgumentNullException("obj");

 

        return new IGroupingWrapper(obj.GetType().GetProperty("Key").GetValue(obj, new object[0]),

            ((IEnumerable)obj).Cast<object>());

    }

}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.