using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security; using System.Threading; using Unity; [assembly: ComCompatibleVersion(1, 0, 3300, 0)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("System.Data.DataSetExtensions.dll")] [assembly: AssemblyDescription("System.Data.DataSetExtensions.dll")] [assembly: AssemblyDefaultAlias("System.Data.DataSetExtensions.dll")] [assembly: AssemblyCompany("Mono development team")] [assembly: AssemblyProduct("Mono Common Language Infrastructure")] [assembly: SatelliteContractVersion("4.0.0.0")] [assembly: AssemblyCopyright("(c) Various Mono authors")] [assembly: AssemblyInformationalVersion("4.6.57.0")] [assembly: AssemblyFileVersion("4.6.57.0")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: CLSCompliant(true)] [assembly: AssemblyDelaySign(true)] [assembly: ComVisible(false)] [assembly: AllowPartiallyTrustedCallers] [assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)] [assembly: SecurityCritical] [assembly: AssemblyVersion("4.0.0.0")] internal static class DataSetUtil { private static readonly Type s_stackOverflowType = typeof(StackOverflowException); private static readonly Type s_outOfMemoryType = typeof(OutOfMemoryException); private static readonly Type s_threadAbortType = typeof(ThreadAbortException); private static readonly Type s_nullReferenceType = typeof(NullReferenceException); private static readonly Type s_accessViolationType = typeof(AccessViolationException); private static readonly Type s_securityType = typeof(SecurityException); internal static void CheckArgumentNull(T argumentValue, string argumentName) where T : class { if (argumentValue == null) { throw ArgumentNull(argumentName); } } private static T TraceException(string trace, T e) { return e; } private static T TraceExceptionAsReturnValue(T e) { return TraceException(" '%ls'\n", e); } internal static ArgumentException Argument(string message) { return TraceExceptionAsReturnValue(new ArgumentException(message)); } internal static ArgumentNullException ArgumentNull(string message) { return TraceExceptionAsReturnValue(new ArgumentNullException(message)); } internal static ArgumentOutOfRangeException ArgumentOutOfRange(string message, string parameterName) { return TraceExceptionAsReturnValue(new ArgumentOutOfRangeException(parameterName, message)); } internal static InvalidCastException InvalidCast(string message) { return TraceExceptionAsReturnValue(new InvalidCastException(message)); } internal static InvalidOperationException InvalidOperation(string message) { return TraceExceptionAsReturnValue(new InvalidOperationException(message)); } internal static NotSupportedException NotSupported(string message) { return TraceExceptionAsReturnValue(new NotSupportedException(message)); } internal static ArgumentOutOfRangeException InvalidEnumerationValue(Type type, int value) { return ArgumentOutOfRange($"The {type.Name} enumeration value, {value.ToString(CultureInfo.InvariantCulture)}, is not valid.", type.Name); } internal static ArgumentOutOfRangeException InvalidDataRowState(DataRowState value) { return InvalidEnumerationValue(typeof(DataRowState), (int)value); } internal static ArgumentOutOfRangeException InvalidLoadOption(LoadOption value) { return InvalidEnumerationValue(typeof(LoadOption), (int)value); } internal static bool IsCatchableExceptionType(Exception e) { Type type = e.GetType(); if (type != s_stackOverflowType && type != s_outOfMemoryType && type != s_threadAbortType && type != s_nullReferenceType && type != s_accessViolationType) { return !s_securityType.IsAssignableFrom(type); } return false; } } internal static class Consts { public const string MonoCorlibVersion = "1A5E0066-58DC-428A-B21C-0AD6CDAE2789"; public const string MonoVersion = "6.13.0.0"; public const string MonoCompany = "Mono development team"; public const string MonoProduct = "Mono Common Language Infrastructure"; public const string MonoCopyright = "(c) Various Mono authors"; public const string FxVersion = "4.0.0.0"; public const string FxFileVersion = "4.6.57.0"; public const string EnvironmentVersion = "4.0.30319.42000"; public const string VsVersion = "0.0.0.0"; public const string VsFileVersion = "11.0.0.0"; private const string PublicKeyToken = "b77a5c561934e089"; public const string AssemblyI18N = "I18N, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblyMono_Http = "Mono.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMono_Posix = "Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMono_Security = "Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756"; public const string AssemblyCorlib = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Data = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Design = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Drawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Messaging = "System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Security = "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Web = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Core = "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; } internal class SR { public const string DataSetLinq_InvalidEnumerationValue = "The {0} enumeration value, {1}, is not valid."; public const string DataSetLinq_EmptyDataRowSource = "The source contains no DataRows."; public const string DataSetLinq_NullDataRow = "The source contains a DataRow reference that is null."; public const string DataSetLinq_CannotLoadDetachedRow = "The source contains a detached DataRow that cannot be copied to the DataTable."; public const string DataSetLinq_CannotCompareDeletedRow = "The DataRowComparer does not work with DataRows that have been deleted since it only compares current values."; public const string DataSetLinq_CannotLoadDeletedRow = "The source contains a deleted DataRow that cannot be copied to the DataTable."; public const string DataSetLinq_NonNullableCast = "Cannot cast DBNull. Value to type '{0}'. Please use a nullable type."; } namespace System.Data { public static class DataRowComparer { public static DataRowComparer Default => DataRowComparer.Default; internal static bool AreEqual(object a, object b) { if (a == b) { return true; } if (a == null || a == DBNull.Value || b == null || b == DBNull.Value) { return false; } if (!a.Equals(b)) { if (a.GetType().IsArray) { return CompareArray((Array)a, b as Array); } return false; } return true; } private static bool AreElementEqual(object a, object b) { if (a == b) { return true; } if (a == null || a == DBNull.Value || b == null || b == DBNull.Value) { return false; } return a.Equals(b); } private static bool CompareArray(Array a, Array b) { if (b == null || 1 != a.Rank || 1 != b.Rank || a.Length != b.Length) { return false; } int num = a.GetLowerBound(0); int num2 = b.GetLowerBound(0); if (a.GetType() == b.GetType() && num == 0 && num2 == 0) { switch (Type.GetTypeCode(a.GetType().GetElementType())) { case TypeCode.Byte: return CompareEquatableArray((byte[])a, (byte[])b); case TypeCode.Int16: return CompareEquatableArray((short[])a, (short[])b); case TypeCode.Int32: return CompareEquatableArray((int[])a, (int[])b); case TypeCode.Int64: return CompareEquatableArray((long[])a, (long[])b); case TypeCode.String: return CompareEquatableArray((string[])a, (string[])b); } } int num3 = num + a.Length; while (num < num3) { if (!AreElementEqual(a.GetValue(num), b.GetValue(num2))) { return false; } num++; num2++; } return true; } private static bool CompareEquatableArray(TElem[] a, TElem[] b) where TElem : IEquatable { for (int i = 0; i < a.Length; i++) { ref readonly TElem reference = ref a[i]; TElem other = b[i]; if (!reference.Equals(other)) { return false; } } return true; } } public sealed class DataRowComparer : IEqualityComparer where TRow : DataRow { private static DataRowComparer s_instance = new DataRowComparer(); public static DataRowComparer Default => s_instance; private DataRowComparer() { } public bool Equals(TRow leftRow, TRow rightRow) { if (leftRow == rightRow) { return true; } if (leftRow == null || rightRow == null) { return false; } if (leftRow.RowState == DataRowState.Deleted || rightRow.RowState == DataRowState.Deleted) { throw global::DataSetUtil.InvalidOperation("The DataRowComparer does not work with DataRows that have been deleted since it only compares current values."); } int count = leftRow.Table.Columns.Count; if (count != rightRow.Table.Columns.Count) { return false; } for (int i = 0; i < count; i++) { if (!DataRowComparer.AreEqual(leftRow[i], rightRow[i])) { return false; } } return true; } public int GetHashCode(TRow row) { global::DataSetUtil.CheckArgumentNull(row, "row"); if (row.RowState == DataRowState.Deleted) { throw global::DataSetUtil.InvalidOperation("The DataRowComparer does not work with DataRows that have been deleted since it only compares current values."); } int result = 0; if (row.Table.Columns.Count > 0) { object obj = row[0]; if (!obj.GetType().IsArray) { result = ((!(obj is ValueType valueType)) ? obj.GetHashCode() : valueType.GetHashCode()); } else { Array array = obj as Array; if (array.Rank > 1) { result = obj.GetHashCode(); } else if (array.Length > 0) { result = array.GetValue(array.GetLowerBound(0)).GetHashCode(); } } } return result; } } public static class DataRowExtensions { private static class UnboxT { internal static readonly Converter s_unbox = Create(); private static Converter Create() { if (default(T) == null) { return ReferenceOrNullableField; } return ValueField; } private static T ReferenceOrNullableField(object value) { if (DBNull.Value != value) { return (T)value; } return default(T); } private static T ValueField(object value) { if (DBNull.Value == value) { throw global::DataSetUtil.InvalidCast($"Cannot cast DBNull. Value to type '{typeof(T).ToString()}'. Please use a nullable type."); } return (T)value; } } public static T Field(this DataRow row, string columnName) { global::DataSetUtil.CheckArgumentNull(row, "row"); return UnboxT.s_unbox(row[columnName]); } public static T Field(this DataRow row, DataColumn column) { global::DataSetUtil.CheckArgumentNull(row, "row"); return UnboxT.s_unbox(row[column]); } public static T Field(this DataRow row, int columnIndex) { global::DataSetUtil.CheckArgumentNull(row, "row"); return UnboxT.s_unbox(row[columnIndex]); } public static T Field(this DataRow row, int columnIndex, DataRowVersion version) { global::DataSetUtil.CheckArgumentNull(row, "row"); return UnboxT.s_unbox(row[columnIndex, version]); } public static T Field(this DataRow row, string columnName, DataRowVersion version) { global::DataSetUtil.CheckArgumentNull(row, "row"); return UnboxT.s_unbox(row[columnName, version]); } public static T Field(this DataRow row, DataColumn column, DataRowVersion version) { global::DataSetUtil.CheckArgumentNull(row, "row"); return UnboxT.s_unbox(row[column, version]); } public static void SetField(this DataRow row, int columnIndex, T value) { global::DataSetUtil.CheckArgumentNull(row, "row"); row[columnIndex] = ((object)value) ?? DBNull.Value; } public static void SetField(this DataRow row, string columnName, T value) { global::DataSetUtil.CheckArgumentNull(row, "row"); row[columnName] = ((object)value) ?? DBNull.Value; } public static void SetField(this DataRow row, DataColumn column, T value) { global::DataSetUtil.CheckArgumentNull(row, "row"); row[column] = ((object)value) ?? DBNull.Value; } } public static class DataTableExtensions { public static EnumerableRowCollection AsEnumerable(this DataTable source) { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source); } public static DataTable CopyToDataTable(this IEnumerable source) where T : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return LoadTableFromEnumerable(source, null, null, null); } public static void CopyToDataTable(this IEnumerable source, DataTable table, LoadOption options) where T : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); global::DataSetUtil.CheckArgumentNull(table, "table"); LoadTableFromEnumerable(source, table, options, null); } public static void CopyToDataTable(this IEnumerable source, DataTable table, LoadOption options, FillErrorEventHandler errorHandler) where T : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); global::DataSetUtil.CheckArgumentNull(table, "table"); LoadTableFromEnumerable(source, table, options, errorHandler); } private static DataTable LoadTableFromEnumerable(IEnumerable source, DataTable table, LoadOption? options, FillErrorEventHandler errorHandler) where T : DataRow { if (options.HasValue) { LoadOption value = options.Value; if ((uint)(value - 1) > 2u) { throw global::DataSetUtil.InvalidLoadOption(options.Value); } } using (IEnumerator enumerator = source.GetEnumerator()) { if (!enumerator.MoveNext()) { return table ?? throw global::DataSetUtil.InvalidOperation("The source contains no DataRows."); } if (table == null) { DataRow current = enumerator.Current; if (current == null) { throw global::DataSetUtil.InvalidOperation("The source contains a DataRow reference that is null."); } table = new DataTable { Locale = CultureInfo.CurrentCulture }; foreach (DataColumn column in current.Table.Columns) { table.Columns.Add(column.ColumnName, column.DataType); } } table.BeginLoadData(); try { do { DataRow current = enumerator.Current; if (current == null) { continue; } object[] values = null; try { switch (current.RowState) { case DataRowState.Detached: if (!current.HasVersion(DataRowVersion.Proposed)) { throw global::DataSetUtil.InvalidOperation("The source contains a detached DataRow that cannot be copied to the DataTable."); } goto case DataRowState.Unchanged; case DataRowState.Unchanged: case DataRowState.Added: case DataRowState.Modified: values = current.ItemArray; if (options.HasValue) { table.LoadDataRow(values, options.Value); } else { table.LoadDataRow(values, fAcceptChanges: true); } break; case DataRowState.Deleted: throw global::DataSetUtil.InvalidOperation("The source contains a deleted DataRow that cannot be copied to the DataTable."); default: throw global::DataSetUtil.InvalidDataRowState(current.RowState); } } catch (Exception ex) { if (!global::DataSetUtil.IsCatchableExceptionType(ex)) { throw; } FillErrorEventArgs e = null; if (errorHandler != null) { e = new FillErrorEventArgs(table, values) { Errors = ex }; errorHandler(enumerator, e); } if (e == null) { throw; } if (!e.Continue) { if ((e.Errors ?? ex) == ex) { throw; } throw e.Errors; } } } while (enumerator.MoveNext()); } finally { table.EndLoadData(); } } return table; } public static DataView AsDataView(this DataTable table) { throw new PlatformNotSupportedException(); } public static DataView AsDataView(this EnumerableRowCollection source) where T : DataRow { throw new PlatformNotSupportedException(); } } public abstract class EnumerableRowCollection : IEnumerable { internal abstract Type ElementType { get; } internal abstract DataTable Table { get; } internal EnumerableRowCollection() { } IEnumerator IEnumerable.GetEnumerator() { return null; } } public class EnumerableRowCollection : EnumerableRowCollection, IEnumerable, IEnumerable { private readonly DataTable _table; private readonly IEnumerable _enumerableRows; private readonly List> _listOfPredicates; private readonly System.Data.SortExpressionBuilder _sortExpression; private readonly Func _selector; internal override Type ElementType => typeof(TRow); internal IEnumerable EnumerableRows => _enumerableRows; internal override DataTable Table => _table; internal EnumerableRowCollection(IEnumerable enumerableRows, bool isDataViewable, DataTable table) { _enumerableRows = enumerableRows; if (isDataViewable) { _table = table; } _listOfPredicates = new List>(); _sortExpression = new System.Data.SortExpressionBuilder(); } internal EnumerableRowCollection(DataTable table) { _table = table; _enumerableRows = table.Rows.Cast(); _listOfPredicates = new List>(); _sortExpression = new System.Data.SortExpressionBuilder(); } internal EnumerableRowCollection(EnumerableRowCollection source, IEnumerable enumerableRows, Func selector) { _enumerableRows = enumerableRows; _selector = selector; if (source != null) { if (source._selector == null) { _table = source._table; } _listOfPredicates = new List>(source._listOfPredicates); _sortExpression = source._sortExpression.Clone(); } else { _listOfPredicates = new List>(); _sortExpression = new System.Data.SortExpressionBuilder(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { return _enumerableRows.GetEnumerator(); } internal void AddPredicate(Func pred) { _listOfPredicates.Add(pred); } internal void AddSortExpression(Func keySelector, bool isDescending, bool isOrderBy) { AddSortExpression(keySelector, Comparer.Default, isDescending, isOrderBy); } internal void AddSortExpression(Func keySelector, IComparer comparer, bool isDescending, bool isOrderBy) { global::DataSetUtil.CheckArgumentNull(keySelector, "keySelector"); global::DataSetUtil.CheckArgumentNull(comparer, "comparer"); _sortExpression.Add((TRow input) => keySelector(input), (object val1, object val2) => ((!isDescending) ? 1 : (-1)) * comparer.Compare((TKey)val1, (TKey)val2), isOrderBy); } internal EnumerableRowCollection() { ThrowStub.ThrowNotSupportedException(); } } public static class EnumerableRowCollectionExtensions { public static EnumerableRowCollection Where(this EnumerableRowCollection source, Func predicate) { EnumerableRowCollection enumerableRowCollection = new EnumerableRowCollection(source, Enumerable.Where(source, predicate), null); enumerableRowCollection.AddPredicate(predicate); return enumerableRowCollection; } public static OrderedEnumerableRowCollection OrderBy(this EnumerableRowCollection source, Func keySelector) { IEnumerable enumerableRows = Enumerable.OrderBy(source, keySelector); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, isDescending: false, isOrderBy: true); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection OrderBy(this EnumerableRowCollection source, Func keySelector, IComparer comparer) { IEnumerable enumerableRows = Enumerable.OrderBy(source, keySelector, comparer); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, comparer, isDescending: false, isOrderBy: true); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection OrderByDescending(this EnumerableRowCollection source, Func keySelector) { IEnumerable enumerableRows = Enumerable.OrderByDescending(source, keySelector); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, isDescending: true, isOrderBy: true); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection OrderByDescending(this EnumerableRowCollection source, Func keySelector, IComparer comparer) { IEnumerable enumerableRows = Enumerable.OrderByDescending(source, keySelector, comparer); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, comparer, isDescending: true, isOrderBy: true); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection ThenBy(this OrderedEnumerableRowCollection source, Func keySelector) { IEnumerable enumerableRows = ((IOrderedEnumerable)source.EnumerableRows).ThenBy(keySelector); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, isDescending: false, isOrderBy: false); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection ThenBy(this OrderedEnumerableRowCollection source, Func keySelector, IComparer comparer) { IEnumerable enumerableRows = ((IOrderedEnumerable)source.EnumerableRows).ThenBy(keySelector, comparer); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, comparer, isDescending: false, isOrderBy: false); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection ThenByDescending(this OrderedEnumerableRowCollection source, Func keySelector) { IEnumerable enumerableRows = ((IOrderedEnumerable)source.EnumerableRows).ThenByDescending(keySelector); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, isDescending: true, isOrderBy: false); return orderedEnumerableRowCollection; } public static OrderedEnumerableRowCollection ThenByDescending(this OrderedEnumerableRowCollection source, Func keySelector, IComparer comparer) { IEnumerable enumerableRows = ((IOrderedEnumerable)source.EnumerableRows).ThenByDescending(keySelector, comparer); OrderedEnumerableRowCollection orderedEnumerableRowCollection = new OrderedEnumerableRowCollection(source, enumerableRows); orderedEnumerableRowCollection.AddSortExpression(keySelector, comparer, isDescending: true, isOrderBy: false); return orderedEnumerableRowCollection; } public static EnumerableRowCollection Select(this EnumerableRowCollection source, Func selector) { IEnumerable enumerableRows = Enumerable.Select(source, selector); return new EnumerableRowCollection(source as EnumerableRowCollection, enumerableRows, selector as Func); } public static EnumerableRowCollection Cast(this EnumerableRowCollection source) { if (source != null && source.ElementType.Equals(typeof(TResult))) { return (EnumerableRowCollection)source; } return new EnumerableRowCollection(Enumerable.Cast(source), typeof(TResult).IsAssignableFrom(source.ElementType) && typeof(DataRow).IsAssignableFrom(typeof(TResult)), source.Table); } } public sealed class OrderedEnumerableRowCollection : EnumerableRowCollection { internal OrderedEnumerableRowCollection(EnumerableRowCollection enumerableTable, IEnumerable enumerableRows) : base(enumerableTable, enumerableRows, (Func)null) { } internal OrderedEnumerableRowCollection() { ThrowStub.ThrowNotSupportedException(); } } internal class SortExpressionBuilder : IComparer> { private LinkedList> _selectors = new LinkedList>(); private LinkedList> _comparers = new LinkedList>(); private LinkedListNode> _currentSelector; private LinkedListNode> _currentComparer; internal int Count => _selectors.Count; internal void Add(Func keySelector, Comparison compare, bool isOrderBy) { if (isOrderBy) { _currentSelector = _selectors.AddFirst(keySelector); _currentComparer = _comparers.AddFirst(compare); } else { _currentSelector = _selectors.AddAfter(_currentSelector, keySelector); _currentComparer = _comparers.AddAfter(_currentComparer, compare); } } public List Select(T row) { List list = new List(); foreach (Func selector in _selectors) { list.Add(selector(row)); } return list; } public int Compare(List a, List b) { int num = 0; foreach (Comparison comparer in _comparers) { int num2 = comparer(a[num], b[num]); if (num2 != 0) { return num2; } num++; } return 0; } internal System.Data.SortExpressionBuilder Clone() { System.Data.SortExpressionBuilder sortExpressionBuilder = new System.Data.SortExpressionBuilder(); foreach (Func selector in _selectors) { if (selector == _currentSelector.Value) { sortExpressionBuilder._currentSelector = sortExpressionBuilder._selectors.AddLast(selector); } else { sortExpressionBuilder._selectors.AddLast(selector); } } foreach (Comparison comparer in _comparers) { if (comparer == _currentComparer.Value) { sortExpressionBuilder._currentComparer = sortExpressionBuilder._comparers.AddLast(comparer); } else { sortExpressionBuilder._comparers.AddLast(comparer); } } return sortExpressionBuilder; } internal System.Data.SortExpressionBuilder CloneCast() { System.Data.SortExpressionBuilder sortExpressionBuilder = new System.Data.SortExpressionBuilder(); foreach (Func selector in _selectors) { if (selector == _currentSelector.Value) { sortExpressionBuilder._currentSelector = sortExpressionBuilder._selectors.AddLast((TResult r) => selector((T)(object)r)); } else { sortExpressionBuilder._selectors.AddLast((TResult r) => selector((T)(object)r)); } } foreach (Comparison comparer in _comparers) { if (comparer == _currentComparer.Value) { sortExpressionBuilder._currentComparer = sortExpressionBuilder._comparers.AddLast(comparer); } else { sortExpressionBuilder._comparers.AddLast(comparer); } } return sortExpressionBuilder; } } [Serializable] public abstract class TypedTableBase : DataTable, IEnumerable, IEnumerable where T : DataRow { protected TypedTableBase() { } protected TypedTableBase(SerializationInfo info, StreamingContext context) : base(info, context) { } public IEnumerator GetEnumerator() { return base.Rows.Cast().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public EnumerableRowCollection Cast() { return new EnumerableRowCollection(this).Cast(); } } public static class TypedTableBaseExtensions { public static EnumerableRowCollection Where(this TypedTableBase source, Func predicate) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source).Where(predicate); } public static OrderedEnumerableRowCollection OrderBy(this TypedTableBase source, Func keySelector) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source).OrderBy(keySelector); } public static OrderedEnumerableRowCollection OrderBy(this TypedTableBase source, Func keySelector, IComparer comparer) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source).OrderBy(keySelector, comparer); } public static OrderedEnumerableRowCollection OrderByDescending(this TypedTableBase source, Func keySelector) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source).OrderByDescending(keySelector); } public static OrderedEnumerableRowCollection OrderByDescending(this TypedTableBase source, Func keySelector, IComparer comparer) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source).OrderByDescending(keySelector, comparer); } public static EnumerableRowCollection Select(this TypedTableBase source, Func selector) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source).Select(selector); } public static EnumerableRowCollection AsEnumerable(this TypedTableBase source) where TRow : DataRow { global::DataSetUtil.CheckArgumentNull(source, "source"); return new EnumerableRowCollection(source); } public static TRow ElementAtOrDefault(this TypedTableBase source, int index) where TRow : DataRow { if (index >= 0 && index < source.Rows.Count) { return (TRow)source.Rows[index]; } return null; } } } namespace Unity { internal sealed class ThrowStub : ObjectDisposedException { public static void ThrowNotSupportedException() { throw new PlatformNotSupportedException(); } } }