CSharp 案例:用 Dynamic 來解決 DataTable 數值累加問題


需求說明

給定一個 DataTable,如果從中取出數值類型列的值並對其累加?
限制:不知該列是何種數值類型。


解決方案

1、將表轉換為 IEnumerable<dynamic>,而后獲取指定的列的值並對其累加;
2、如果該值類型為 DBNull,則視作 0;
3、使用 double,確保最小程度丟失精度。


關鍵方法 AsDynamicEnumerable

該方法出自 http://codego.net/368045/ ,關鍵方法為:

public static class DynamicTable
{
    public static IEnumerable<dynamic> AsDynamicEnumerable(this DataTable table)
    {
        //table.CheckNull("table");
        return table.AsEnumerable().Select(row => new DynamicRow(row));
    }
    private sealed class DynamicRow : DynamicObject
    {
        private readonly DataRow _row;
        internal DynamicRow(DataRow row) { _row = row; }
            
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var retVal = _row.Table.Columns.Contains(binder.Name);
            result = retVal ? _row[binder.Name] : null;
            return retVal;
        }
    }
}

使用與單元測試


緣何選擇 Double?

從 int、uint、long 或 ulong 轉換為 float,從 long 或 ulong 轉換為 double 會丟失精度(loss of precision),但不會導致數量級的丟失(loss of magnitude)。其它的隱式數制轉換不會丟失任何信息。
——《C# Language Specification 5.0 (翻譯)第六章 轉換》,「隱式數值轉換」,本文作者譯


需要改進之處

事實上這個方法並非健全之策。如果你對數值的精度要求比較高,或者你選擇使用 Decimal 類型,則其可能丟失的精度會讓你不可容忍。另外,還需要判斷該列對象是否為數值類型的值,如果不是的話該如何處理。最后,同時也最關鍵的是,如果不用DataTable,那么就沒有這些煩惱了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM