Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.DataSetExtensions / System / Data / DataRowExtensions.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="DataRowExtenstions.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">spather</owner>
7 //------------------------------------------------------------------------------
8 using System;
9 using System.Data.DataSetExtensions;
10
11 namespace System.Data {
12     
13     /// <summary>
14     /// This static class defines the DataRow extension methods.
15     /// </summary>
16     public static class DataRowExtensions {
17     
18         /// <summary>
19         ///  This method provides access to the values in each of the columns in a given row. 
20         ///  This method makes casts unnecessary when accessing columns. 
21         ///  Additionally, Field supports nullable types and maps automatically between DBNull and 
22         ///  Nullable when the generic type is nullable. 
23         /// </summary>
24         /// <param name="row">
25         ///   The input DataRow
26         /// </param>
27         /// <param name="columnName">
28         ///   The input column name specificy which row value to retrieve.
29         /// </param>
30         /// <returns>
31         ///   The DataRow value for the column specified.
32         /// </returns> 
33         public static T Field<T>(this DataRow row, string columnName) {
34             DataSetUtil.CheckArgumentNull(row, "row");
35             return UnboxT<T>.Unbox(row[columnName]);
36         }
37         
38         /// <summary>
39         ///  This method provides access to the values in each of the columns in a given row. 
40         ///  This method makes casts unnecessary when accessing columns. 
41         ///  Additionally, Field supports nullable types and maps automatically between DBNull and 
42         ///  Nullable when the generic type is nullable. 
43         /// </summary>
44         /// <param name="row">
45         ///   The input DataRow
46         /// </param>
47         /// <param name="column">
48         ///   The input DataColumn specificy which row value to retrieve.
49         /// </param>
50         /// <returns>
51         ///   The DataRow value for the column specified.
52         /// </returns> 
53         public static T Field<T>(this DataRow row, DataColumn column) {
54             DataSetUtil.CheckArgumentNull(row, "row");
55             return UnboxT<T>.Unbox(row[column]);
56         }
57
58         /// <summary>
59         ///  This method provides access to the values in each of the columns in a given row. 
60         ///  This method makes casts unnecessary when accessing columns. 
61         ///  Additionally, Field supports nullable types and maps automatically between DBNull and 
62         ///  Nullable when the generic type is nullable. 
63         /// </summary>
64         /// <param name="row">
65         ///   The input DataRow
66         /// </param>
67         /// <param name="columnIndex">
68         ///   The input ordinal specificy which row value to retrieve.
69         /// </param>
70         /// <returns>
71         ///   The DataRow value for the column specified.
72         /// </returns> 
73         public static T Field<T>(this DataRow row, int columnIndex) {
74             DataSetUtil.CheckArgumentNull(row, "row");
75             return UnboxT<T>.Unbox(row[columnIndex]);
76         }
77
78         /// <summary>
79         ///  This method provides access to the values in each of the columns in a given row. 
80         ///  This method makes casts unnecessary when accessing columns. 
81         ///  Additionally, Field supports nullable types and maps automatically between DBNull and 
82         ///  Nullable when the generic type is nullable. 
83         /// </summary>
84         /// <param name="row">
85         ///   The input DataRow
86         /// </param>
87         /// <param name="columnIndex">
88         ///   The input ordinal specificy which row value to retrieve.
89         /// </param>
90         /// <param name="version">
91         ///   The DataRow version for which row value to retrieve.
92         /// </param>
93         /// <returns>
94         ///   The DataRow value for the column specified.
95         /// </returns> 
96         public static T Field<T>(this DataRow row, int columnIndex, DataRowVersion version) {
97             DataSetUtil.CheckArgumentNull(row, "row");
98             return UnboxT<T>.Unbox(row[columnIndex, version]);
99         }
100
101         /// <summary>
102         ///  This method provides access to the values in each of the columns in a given row. 
103         ///  This method makes casts unnecessary when accessing columns. 
104         ///  Additionally, Field supports nullable types and maps automatically between DBNull and 
105         ///  Nullable when the generic type is nullable. 
106         /// </summary>
107         /// <param name="row">
108         ///   The input DataRow
109         /// </param>
110         /// <param name="columnName">
111         ///   The input column name specificy which row value to retrieve.
112         /// </param>
113         /// <param name="version">
114         ///   The DataRow version for which row value to retrieve.
115         /// </param>
116         /// <returns>
117         ///   The DataRow value for the column specified.
118         /// </returns> 
119         public static T Field<T>(this DataRow row, string columnName, DataRowVersion version) {
120             DataSetUtil.CheckArgumentNull(row, "row");
121             return UnboxT<T>.Unbox(row[columnName, version]);
122         }
123
124         /// <summary>
125         ///  This method provides access to the values in each of the columns in a given row. 
126         ///  This method makes casts unnecessary when accessing columns. 
127         ///  Additionally, Field supports nullable types and maps automatically between DBNull and 
128         ///  Nullable when the generic type is nullable. 
129         /// </summary>
130         /// <param name="row">
131         ///   The input DataRow
132         /// </param>
133         /// <param name="column">
134         ///   The input DataColumn specificy which row value to retrieve.
135         /// </param>
136         /// <param name="version">
137         ///   The DataRow version for which row value to retrieve.
138         /// </param>
139         /// <returns>
140         ///   The DataRow value for the column specified.
141         /// </returns> 
142         public static T Field<T>(this DataRow row, DataColumn column, DataRowVersion version) {
143             DataSetUtil.CheckArgumentNull(row, "row");
144             return UnboxT<T>.Unbox(row[column, version]);
145         }
146
147         /// <summary>
148         ///  This method sets a new value for the specified column for the DataRow it\92s called on. 
149         /// </summary>
150         /// <param name="row">
151         ///   The input DataRow.
152         /// </param>
153         /// <param name="columnIndex">
154         ///   The input ordinal specifying which row value to set.
155         /// </param>
156         /// <param name="value">
157         ///   The new row value for the specified column.
158         /// </param>
159         public static void SetField<T>(this DataRow row, int columnIndex, T value) {
160             DataSetUtil.CheckArgumentNull(row, "row");
161             row[columnIndex] = (object)value ?? DBNull.Value;
162         }
163         
164         /// <summary>
165         ///  This method sets a new value for the specified column for the DataRow it\92s called on. 
166         /// </summary>
167         /// <param name="row">
168         ///   The input DataRow.
169         /// </param>
170         /// <param name="columnName">
171         ///   The input column name specificy which row value to retrieve.
172         /// </param>
173         /// <param name="value">
174         ///   The new row value for the specified column.
175         /// </param>
176         public static void SetField<T>(this DataRow row, string columnName, T value) {
177             DataSetUtil.CheckArgumentNull(row, "row");
178             row[columnName] = (object)value ?? DBNull.Value;
179         }
180
181         /// <summary>
182         ///  This method sets a new value for the specified column for the DataRow it\92s called on. 
183         /// </summary>
184         /// <param name="row">
185         ///   The input DataRow.
186         /// </param>
187         /// <param name="column">
188         ///   The input DataColumn specificy which row value to retrieve.
189         /// </param>
190         /// <param name="value">
191         ///   The new row value for the specified column.
192         /// </param>
193         public static void SetField<T>(this DataRow row, DataColumn column, T value) {
194             DataSetUtil.CheckArgumentNull(row, "row");
195             row[column] = (object)value ?? DBNull.Value;
196         }
197
198         private static class UnboxT<T>
199         {
200             internal static readonly Converter<object, T> Unbox = Create(typeof(T));
201
202             private static Converter<object, T> Create(Type type)
203             {
204                 if (type.IsValueType)
205                 {
206                     if (type.IsGenericType && !type.IsGenericTypeDefinition && (typeof(Nullable<>) == type.GetGenericTypeDefinition()))
207                     {
208                         return (Converter<object, T>)Delegate.CreateDelegate(
209                             typeof(Converter<object, T>),
210                                 typeof(UnboxT<T>)
211                                     .GetMethod("NullableField", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
212                                     .MakeGenericMethod(type.GetGenericArguments()[0]));
213                     }
214                     return ValueField;
215                 }
216                 return ReferenceField;
217             }
218
219             private static T ReferenceField(object value)
220             {
221                 return ((DBNull.Value == value) ? default(T) : (T)value);
222             }
223
224             private static T ValueField(object value)
225             {
226                 if (DBNull.Value == value)
227                 {
228                     throw DataSetUtil.InvalidCast(Strings.DataSetLinq_NonNullableCast(typeof(T).ToString()));
229                 }
230                 return (T)value;
231             }
232
233             private static Nullable<TElem> NullableField<TElem>(object value) where TElem : struct
234             {
235                 if (DBNull.Value == value)
236                 {
237                     return default(Nullable<TElem>);
238                 }
239                 return new Nullable<TElem>((TElem)value);
240             }
241         }
242     }
243 }