1616using System ;
1717using System . Collections . Generic ;
1818using System . Linq ;
19+ using System . Reflection ;
1920using System . Runtime . CompilerServices ;
21+ using MongoDB . Bson ;
2022
2123namespace MongoDB . Driver . Linq . Linq3Implementation . Misc
2224{
@@ -52,6 +54,14 @@ internal static class TypeExtensions
5254 typeof ( ValueTuple < , , , , , , , > )
5355 } ;
5456
57+ public static object GetDefaultValue ( this Type type )
58+ {
59+ var genericMethod = typeof ( TypeExtensions )
60+ . GetMethod ( nameof ( GetDefaultValueGeneric ) , BindingFlags . NonPublic | BindingFlags . Static )
61+ . MakeGenericMethod ( type ) ;
62+ return genericMethod . Invoke ( null , null ) ;
63+ }
64+
5565 public static Type GetIEnumerableGenericInterface ( this Type enumerableType )
5666 {
5767 if ( enumerableType . TryGetIEnumerableGenericInterface ( out var ienumerableGenericInterface ) )
@@ -136,6 +146,18 @@ public static bool ImplementsIList(this Type type, out Type itemType)
136146 return false ;
137147 }
138148
149+ public static bool ImplementsIQueryable ( this Type type , out Type itemType )
150+ {
151+ if ( TryGetIQueryableGenericInterface ( type , out var iqueryableType ) )
152+ {
153+ itemType = iqueryableType . GetGenericArguments ( ) [ 0 ] ;
154+ return true ;
155+ }
156+
157+ itemType = null ;
158+ return false ;
159+ }
160+
139161 public static bool Is ( this Type type , Type comparand )
140162 {
141163 if ( type == comparand )
@@ -175,6 +197,28 @@ public static bool IsArray(this Type type, out Type itemType)
175197 return false ;
176198 }
177199
200+ public static bool IsBooleanOrNullableBoolean ( this Type type )
201+ {
202+ return
203+ type == typeof ( bool ) ||
204+ type . IsNullable ( out var valueType ) && valueType == typeof ( bool ) ;
205+ }
206+
207+ public static bool IsConvertibleToEnum ( this Type type )
208+ {
209+ return
210+ type == typeof ( sbyte ) ||
211+ type == typeof ( short ) ||
212+ type == typeof ( int ) ||
213+ type == typeof ( long ) ||
214+ type == typeof ( byte ) ||
215+ type == typeof ( ushort ) ||
216+ type == typeof ( uint ) ||
217+ type == typeof ( ulong ) ||
218+ type == typeof ( Enum ) ||
219+ type == typeof ( string ) ;
220+ }
221+
178222 public static bool IsEnum ( this Type type , out Type underlyingType )
179223 {
180224 if ( type . IsEnum )
@@ -189,27 +233,15 @@ public static bool IsEnum(this Type type, out Type underlyingType)
189233 }
190234 }
191235
192- public static bool IsEnum ( this Type type , out Type enumType , out Type underlyingType )
236+ public static bool IsEnumOrNullableEnum ( this Type type , out Type enumType , out Type underlyingType )
193237 {
194- if ( type . IsEnum )
238+ if ( type . IsEnum ( out underlyingType ) )
195239 {
196240 enumType = type ;
197- underlyingType = Enum . GetUnderlyingType ( type ) ;
198241 return true ;
199242 }
200- else
201- {
202- enumType = null ;
203- underlyingType = null ;
204- return false ;
205- }
206- }
207243
208- public static bool IsEnumOrNullableEnum ( this Type type , out Type enumType , out Type underlyingType )
209- {
210- return
211- type . IsEnum ( out enumType , out underlyingType ) ||
212- type . IsNullableEnum ( out enumType , out underlyingType ) ;
244+ return IsNullableEnum ( type , out enumType , out underlyingType ) ;
213245 }
214246
215247 public static bool IsNullable ( this Type type )
@@ -236,18 +268,54 @@ public static bool IsNullableEnum(this Type type)
236268 return type . IsNullable ( out var valueType ) && valueType . IsEnum ;
237269 }
238270
271+ public static bool IsNullableEnum ( this Type type , out Type enumType )
272+ {
273+ if ( type . IsNullable ( out var valueType ) && valueType . IsEnum )
274+ {
275+ enumType = valueType ;
276+ return true ;
277+ }
278+
279+ enumType = null ;
280+ return false ;
281+ }
282+
239283 public static bool IsNullableEnum ( this Type type , out Type enumType , out Type underlyingType )
240284 {
285+ if ( type . IsNullable ( out var valueType ) && valueType . IsEnum ( out underlyingType ) )
286+ {
287+ enumType = valueType ;
288+ return true ;
289+ }
290+
241291 enumType = null ;
242292 underlyingType = null ;
243- return type . IsNullable ( out var valueType ) && valueType . IsEnum ( out enumType , out underlyingType ) ;
293+ return false ;
244294 }
245295
246296 public static bool IsNullableOf ( this Type type , Type valueType )
247297 {
248298 return type . IsNullable ( out var nullableValueType ) && nullableValueType == valueType ;
249299 }
250300
301+ public static bool IsNumeric ( this Type type )
302+ {
303+ return
304+ type == typeof ( int ) ||
305+ type == typeof ( long ) ||
306+ type == typeof ( double ) ||
307+ type == typeof ( float ) ||
308+ type == typeof ( decimal ) ||
309+ type == typeof ( Decimal128 ) ;
310+ }
311+
312+ public static bool IsNumericOrNullableNumeric ( this Type type )
313+ {
314+ return
315+ type . IsNumeric ( ) ||
316+ type . IsNullable ( out var valueType ) && valueType . IsNumeric ( ) ;
317+ }
318+
251319 public static bool IsSameAsOrNullableOf ( this Type type , Type valueType )
252320 {
253321 return type == valueType || type . IsNullableOf ( valueType ) ;
@@ -332,5 +400,31 @@ public static bool TryGetIListGenericInterface(this Type type, out Type ilistGen
332400 ilistGenericInterface = null ;
333401 return false ;
334402 }
403+
404+ public static bool TryGetIQueryableGenericInterface ( this Type type , out Type iqueryableGenericInterface )
405+ {
406+ if ( type . IsGenericType && type . GetGenericTypeDefinition ( ) == typeof ( IQueryable < > ) )
407+ {
408+ iqueryableGenericInterface = type ;
409+ return true ;
410+ }
411+
412+ foreach ( var interfaceType in type . GetInterfaces ( ) )
413+ {
414+ if ( interfaceType . IsGenericType && interfaceType . GetGenericTypeDefinition ( ) == typeof ( IQueryable < > ) )
415+ {
416+ iqueryableGenericInterface = interfaceType ;
417+ return true ;
418+ }
419+ }
420+
421+ iqueryableGenericInterface = null ;
422+ return false ;
423+ }
424+
425+ private static TValue GetDefaultValueGeneric < TValue > ( )
426+ {
427+ return default ( TValue ) ;
428+ }
335429 }
336430}
0 commit comments