• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 26594173245

28 May 2026 06:28PM UTC coverage: 55.553% (+0.7%) from 54.902%
26594173245

push

github

pwelter34
Move JSON support, add docs and examples

1358 of 3215 branches covered (42.24%)

Branch coverage included in aggregate %.

103 of 234 new or added lines in 9 files covered. (44.02%)

371 existing lines in 26 files now uncovered.

4389 of 7130 relevant lines covered (61.56%)

312.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

25.63
/src/FluentCommand/Extensions/ConvertExtensions.cs
1
using System.Globalization;
2

3
namespace FluentCommand.Extensions;
4

5
/// <summary>
6
/// Provides extension methods for safely converting string values to various base data types, supporting nullable types and culture-specific formatting.
7
/// </summary>
8
public static class ConvertExtensions
9
{
10
    /// <summary>
11
    /// Converts the specified string representation of a logical value to its Boolean equivalent.
12
    /// Accepts common true/false representations such as "true", "false", "yes", "no", "1", "0", "on", "off", "y", "n", "t", "f", and is case-insensitive.
13
    /// </summary>
14
    /// <param name="value">A string containing the logical value to convert.</param>
15
    /// <returns>
16
    /// <c>true</c> if <paramref name="value"/> represents a true value; otherwise, <c>false</c>.
17
    /// </returns>
18
    public static bool ToBoolean(this string? value)
19
    {
20
        if (value == null)
4!
21
            return false;
×
22

23
        if (bool.TryParse(value, out var result))
4✔
24
            return result;
3✔
25

26
        string v = value.Trim();
1✔
27

28
        if (string.Equals(v, "t", StringComparison.OrdinalIgnoreCase)
1!
29
            || string.Equals(v, "true", StringComparison.OrdinalIgnoreCase)
1✔
30
            || string.Equals(v, "y", StringComparison.OrdinalIgnoreCase)
1✔
31
            || string.Equals(v, "yes", StringComparison.OrdinalIgnoreCase)
1✔
32
            || string.Equals(v, "1", StringComparison.OrdinalIgnoreCase)
1✔
33
            || string.Equals(v, "x", StringComparison.OrdinalIgnoreCase)
1✔
34
            || string.Equals(v, "on", StringComparison.OrdinalIgnoreCase))
1✔
35
            return true;
×
36

37
        return false;
1✔
38
    }
39

40
    /// <summary>
41
    /// Converts the specified string representation of a number to an equivalent 8-bit unsigned integer.
42
    /// </summary>
43
    /// <param name="value">A string containing the number to convert.</param>
44
    /// <returns>
45
    /// An 8-bit unsigned integer equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
46
    /// </returns>
47
    public static byte? ToByte(this string? value)
48
    {
49
        if (value == null)
×
50
            return null;
×
51

52
        if (byte.TryParse(value, out var result))
×
53
            return result;
×
54

55
        return null;
×
56
    }
57

58
    /// <summary>
59
    /// Converts the specified string representation of a number to an equivalent 8-bit unsigned integer, using the specified culture-specific formatting information.
60
    /// </summary>
61
    /// <param name="value">A string containing the number to convert.</param>
62
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
63
    /// <returns>
64
    /// An 8-bit unsigned integer equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
65
    /// </returns>
66
    public static byte? ToByte(this string? value, IFormatProvider provider)
67
    {
68
        if (value == null)
×
69
            return null;
×
70

71
        if (byte.TryParse(value, NumberStyles.Integer, provider, out var result))
×
72
            return result;
×
73

74
        return null;
×
75
    }
76

77
    /// <summary>
78
    /// Converts the specified string representation of a date and time to an equivalent <see cref="DateTime"/> value.
79
    /// Attempts multiple common date formats.
80
    /// </summary>
81
    /// <param name="value">The string representation of a date and time.</param>
82
    /// <returns>
83
    /// The <see cref="DateTime"/> equivalent of <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
84
    /// </returns>
85
    public static DateTime? ToDateTime(this string? value)
86
    {
87
        if (value == null)
×
88
            return null;
×
89

90
        if (DateTime.TryParse(value, out var result))
×
91
            return result;
×
92

93
        if (DateTime.TryParseExact(value, "M/d/yyyy hh:mm:ss tt", CultureInfo.CurrentCulture, DateTimeStyles.None, out result))
×
94
            return result;
×
95

96
        if (DateTime.TryParseExact(value, "M/d/yyyy", CultureInfo.CurrentCulture, DateTimeStyles.None, out result))
×
97
            return result;
×
98

99
        return null;
×
100
    }
101

102
    /// <summary>
103
    /// Converts the specified string representation of a date and time to an equivalent <see cref="DateTime"/> value, using the specified culture-specific formatting information.
104
    /// Attempts multiple common date formats.
105
    /// </summary>
106
    /// <param name="value">A string containing a date and time to convert.</param>
107
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
108
    /// <returns>
109
    /// The <see cref="DateTime"/> equivalent of <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
110
    /// </returns>
111
    public static DateTime? ToDateTime(this string? value, IFormatProvider provider)
112
    {
113
        if (value == null)
×
114
            return null;
×
115

116
        if (DateTime.TryParse(value, out var result))
×
117
            return result;
×
118

119
        if (DateTime.TryParseExact(value, "M/d/yyyy hh:mm:ss tt", provider, DateTimeStyles.None, out result))
×
120
            return result;
×
121

122
        if (DateTime.TryParseExact(value, "M/d/yyyy", provider, DateTimeStyles.None, out result))
×
123
            return result;
×
124

125
        return null;
×
126
    }
127

128
    /// <summary>
129
    /// Converts the specified string representation of a number to an equivalent decimal number.
130
    /// </summary>
131
    /// <param name="value">A string containing a number to convert.</param>
132
    /// <returns>
133
    /// A <see cref="decimal"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
134
    /// </returns>
135
    public static decimal? ToDecimal(this string? value)
136
    {
137
        if (value == null)
×
138
            return null;
×
139

140
        if (decimal.TryParse(value, NumberStyles.Currency, CultureInfo.CurrentCulture, out var result))
×
141
            return result;
×
142

143
        return null;
×
144
    }
145

146
    /// <summary>
147
    /// Converts the specified string representation of a number to an equivalent decimal number, using the specified culture-specific formatting information.
148
    /// </summary>
149
    /// <param name="value">A string containing a number to convert.</param>
150
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
151
    /// <returns>
152
    /// A <see cref="decimal"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
153
    /// </returns>
154
    public static decimal? ToDecimal(this string? value, IFormatProvider provider)
155
    {
156
        if (value == null)
×
157
            return null;
×
158

159
        if (decimal.TryParse(value, NumberStyles.Currency, provider, out var result))
×
160
            return result;
×
161

162
        return null;
×
163
    }
164

165
    /// <summary>
166
    /// Converts the specified string representation of a number to an equivalent double-precision floating-point number.
167
    /// </summary>
168
    /// <param name="value">A string containing the number to convert.</param>
169
    /// <returns>
170
    /// A <see cref="double"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
171
    /// </returns>
172
    public static double? ToDouble(this string? value)
173
    {
174
        if (value == null)
×
175
            return null;
×
176

177
        if (double.TryParse(value, out var result))
×
178
            return result;
×
179

180
        return null;
×
181
    }
182

183
    /// <summary>
184
    /// Converts the specified string representation of a number to an equivalent double-precision floating-point number, using the specified culture-specific formatting information.
185
    /// </summary>
186
    /// <param name="value">A string containing the number to convert.</param>
187
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
188
    /// <returns>
189
    /// A <see cref="double"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
190
    /// </returns>
191
    public static double? ToDouble(this string? value, IFormatProvider provider)
192
    {
193
        if (value == null)
×
194
            return null;
×
195

196
        if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider, out var result))
×
197
            return result;
×
198

199
        return null;
×
200
    }
201

202
    /// <summary>
203
    /// Converts the specified string representation of a number to an equivalent 16-bit signed integer.
204
    /// </summary>
205
    /// <param name="value">A string containing the number to convert.</param>
206
    /// <returns>
207
    /// A <see cref="short"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
208
    /// </returns>
209
    public static short? ToInt16(this string? value)
210
    {
211
        if (value == null)
×
212
            return null;
×
213

214
        if (short.TryParse(value, out var result))
×
215
            return result;
×
216

217
        return null;
×
218
    }
219

220
    /// <summary>
221
    /// Converts the specified string representation of a number to an equivalent 16-bit signed integer, using the specified culture-specific formatting information.
222
    /// </summary>
223
    /// <param name="value">A string containing the number to convert.</param>
224
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
225
    /// <returns>
226
    /// A <see cref="short"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
227
    /// </returns>
228
    public static short? ToInt16(this string? value, IFormatProvider provider)
229
    {
230
        if (value == null)
×
231
            return null;
×
232

233
        if (short.TryParse(value, NumberStyles.Integer, provider, out var result))
×
234
            return result;
×
235

236
        return null;
×
237
    }
238

239
    /// <summary>
240
    /// Converts the specified string representation of a number to an equivalent 32-bit signed integer.
241
    /// </summary>
242
    /// <param name="value">A string containing the number to convert.</param>
243
    /// <returns>
244
    /// An <see cref="int"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
245
    /// </returns>
246
    public static int? ToInt32(this string? value)
247
    {
248
        if (value == null)
3!
249
            return null;
×
250

251
        if (int.TryParse(value, out var result))
3✔
252
            return result;
2✔
253

254
        return null;
1✔
255
    }
256

257
    /// <summary>
258
    /// Converts the specified string representation of a number to an equivalent 32-bit signed integer, using the specified culture-specific formatting information.
259
    /// </summary>
260
    /// <param name="value">A string containing the number to convert.</param>
261
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
262
    /// <returns>
263
    /// An <see cref="int"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
264
    /// </returns>
265
    public static int? ToInt32(this string? value, IFormatProvider provider)
266
    {
267
        if (value == null)
×
268
            return null;
×
269

270
        if (int.TryParse(value, NumberStyles.Integer, provider, out var result))
×
271
            return result;
×
272

273
        return null;
×
274
    }
275

276
    /// <summary>
277
    /// Converts the specified string representation of a number to an equivalent 64-bit signed integer.
278
    /// </summary>
279
    /// <param name="value">A string containing a number to convert.</param>
280
    /// <returns>
281
    /// A <see cref="long"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
282
    /// </returns>
283
    public static long? ToInt64(this string? value)
284
    {
285
        if (value == null)
×
286
            return null;
×
287

288
        if (long.TryParse(value, out var result))
×
289
            return result;
×
290

291
        return null;
×
292
    }
293

294
    /// <summary>
295
    /// Converts the specified string representation of a number to an equivalent 64-bit signed integer, using the specified culture-specific formatting information.
296
    /// </summary>
297
    /// <param name="value">A string containing the number to convert.</param>
298
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
299
    /// <returns>
300
    /// A <see cref="long"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
301
    /// </returns>
302
    public static long? ToInt64(this string? value, IFormatProvider provider)
303
    {
304
        if (value == null)
×
305
            return null;
×
306

307
        if (long.TryParse(value, NumberStyles.Integer, provider, out var result))
×
308
            return result;
×
309

310
        return null;
×
311
    }
312

313
    /// <summary>
314
    /// Converts the specified string representation of a number to an equivalent single-precision floating-point number.
315
    /// </summary>
316
    /// <param name="value">A string containing the number to convert.</param>
317
    /// <returns>
318
    /// A <see cref="float"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
319
    /// </returns>
320
    public static float? ToSingle(this string? value)
321
    {
322
        if (value == null)
×
323
            return null;
×
324

325
        if (float.TryParse(value, out var result))
×
326
            return result;
×
327

328
        return null;
×
329
    }
330

331
    /// <summary>
332
    /// Converts the specified string representation of a number to an equivalent single-precision floating-point number, using the specified culture-specific formatting information.
333
    /// </summary>
334
    /// <param name="value">A string containing the number to convert.</param>
335
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
336
    /// <returns>
337
    /// A <see cref="float"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
338
    /// </returns>
339
    public static float? ToSingle(this string? value, IFormatProvider provider)
340
    {
341
        if (value == null)
×
342
            return null;
×
343

344
        if (float.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider, out var result))
×
345
            return result;
×
346

347
        return null;
×
348
    }
349

350
    /// <summary>
351
    /// Converts the specified string representation of a number to an equivalent 16-bit unsigned integer.
352
    /// </summary>
353
    /// <param name="value">A string containing the number to convert.</param>
354
    /// <returns>
355
    /// A <see cref="ushort"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
356
    /// </returns>
357
    public static ushort? ToUInt16(this string? value)
358
    {
359
        if (value == null)
×
360
            return null;
×
361

362
        if (ushort.TryParse(value, out var result))
×
363
            return result;
×
364

365
        return null;
×
366
    }
367

368
    /// <summary>
369
    /// Converts the specified string representation of a number to an equivalent 16-bit unsigned integer, using the specified culture-specific formatting information.
370
    /// </summary>
371
    /// <param name="value">A string containing the number to convert.</param>
372
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
373
    /// <returns>
374
    /// A <see cref="ushort"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
375
    /// </returns>
376
    public static ushort? ToUInt16(this string? value, IFormatProvider provider)
377
    {
378
        if (value == null)
×
379
            return null;
×
380

381
        if (ushort.TryParse(value, NumberStyles.Integer, provider, out var result))
×
382
            return result;
×
383

384
        return null;
×
385
    }
386

387
    /// <summary>
388
    /// Converts the specified string representation of a number to an equivalent 32-bit unsigned integer.
389
    /// </summary>
390
    /// <param name="value">A string containing the number to convert.</param>
391
    /// <returns>
392
    /// A <see cref="uint"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
393
    /// </returns>
394
    public static uint? ToUInt32(this string? value)
395
    {
396
        if (value == null)
×
397
            return null;
×
398

399
        if (uint.TryParse(value, out var result))
×
400
            return result;
×
401

402
        return null;
×
403
    }
404

405
    /// <summary>
406
    /// Converts the specified string representation of a number to an equivalent 32-bit unsigned integer, using the specified culture-specific formatting information.
407
    /// </summary>
408
    /// <param name="value">A string containing the number to convert.</param>
409
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
410
    /// <returns>
411
    /// A <see cref="uint"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
412
    /// </returns>
413
    public static uint? ToUInt32(this string? value, IFormatProvider provider)
414
    {
415
        if (value == null)
×
416
            return null;
×
417

418
        if (uint.TryParse(value, NumberStyles.Integer, provider, out var result))
×
419
            return result;
×
420

421
        return null;
×
422
    }
423

424
    /// <summary>
425
    /// Converts the specified string representation of a number to an equivalent 64-bit unsigned integer.
426
    /// </summary>
427
    /// <param name="value">A string containing the number to convert.</param>
428
    /// <returns>
429
    /// A <see cref="ulong"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
430
    /// </returns>
431
    public static ulong? ToUInt64(this string? value)
432
    {
433
        if (value == null)
×
434
            return null;
×
435

436
        if (ulong.TryParse(value, out var result))
×
437
            return result;
×
438

439
        return null;
×
440
    }
441

442
    /// <summary>
443
    /// Converts the specified string representation of a number to an equivalent 64-bit unsigned integer, using the specified culture-specific formatting information.
444
    /// </summary>
445
    /// <param name="value">A string containing the number to convert.</param>
446
    /// <param name="provider">An object supplying culture-specific formatting information.</param>
447
    /// <returns>
448
    /// A <see cref="ulong"/> equivalent to <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
449
    /// </returns>
450
    public static ulong? ToUInt64(this string? value, IFormatProvider provider)
451
    {
452
        if (value == null)
×
453
            return null;
×
454

455
        if (ulong.TryParse(value, NumberStyles.Integer, provider, out var result))
×
456
            return result;
×
457

458
        return null;
×
459
    }
460

461
    /// <summary>
462
    /// Converts the specified string to an equivalent <see cref="TimeSpan"/> value.
463
    /// </summary>
464
    /// <param name="value">The string representation of a <see cref="TimeSpan"/>.</param>
465
    /// <returns>
466
    /// The <see cref="TimeSpan"/> equivalent of <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
467
    /// </returns>
468
    public static TimeSpan? ToTimeSpan(this string? value)
469
    {
470
        if (value == null)
×
471
            return null;
×
472

473
        if (TimeSpan.TryParse(value, out var result))
×
474
            return result;
×
475

476
        return null;
×
477
    }
478

479
    /// <summary>
480
    /// Converts the specified string to an equivalent <see cref="Guid"/> value.
481
    /// </summary>
482
    /// <param name="value">The string representation of a <see cref="Guid"/>.</param>
483
    /// <returns>
484
    /// The <see cref="Guid"/> equivalent of <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
485
    /// </returns>
486
    public static Guid? ToGuid(this string? value)
487
    {
488
        if (value == null)
5!
489
            return null;
×
490

491
        if (Guid.TryParse(value, out var result))
5!
492
            return result;
5✔
493

494
        return null;
×
495
    }
496

497
#if NET6_0_OR_GREATER
498
    /// <summary>
499
    /// Converts the specified string to an equivalent <see cref="DateOnly"/> value.
500
    /// Attempts to parse as <see cref="DateOnly"/>, <see cref="DateTime"/>, or <see cref="DateTimeOffset"/>.
501
    /// </summary>
502
    /// <param name="value">The string representation of a <see cref="DateOnly"/>.</param>
503
    /// <returns>
504
    /// The <see cref="DateOnly"/> equivalent of <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
505
    /// </returns>
506
    public static DateOnly? ToDateOnly(this string? value)
507
    {
508
        if (value == null)
3!
509
            return null;
×
510

511
        if (DateOnly.TryParse(value, out var dateOnly))
3✔
512
            return dateOnly;
2✔
513

514
        if (DateTime.TryParse(value, out var dateTime))
1!
515
            return DateOnly.FromDateTime(dateTime);
×
516

517
        if (DateTimeOffset.TryParse(value, out var dateTimeOffset))
1!
518
            return DateOnly.FromDateTime(dateTimeOffset.DateTime);
×
519

520
        return null;
1✔
521
    }
522

523
    /// <summary>
524
    /// Converts the specified string to an equivalent <see cref="TimeOnly"/> value.
525
    /// Attempts to parse as <see cref="TimeOnly"/>, <see cref="TimeSpan"/>, <see cref="DateTime"/>, or <see cref="DateTimeOffset"/>.
526
    /// </summary>
527
    /// <param name="value">The string representation of a <see cref="TimeOnly"/>.</param>
528
    /// <returns>
529
    /// The <see cref="TimeOnly"/> equivalent of <paramref name="value"/>, or <c>null</c> if conversion fails or <paramref name="value"/> is <c>null</c>.
530
    /// </returns>
531
    public static TimeOnly? ToTimeOnly(this string? value)
532
    {
533
        if (value == null)
×
534
            return null;
×
535

536
        if (TimeOnly.TryParse(value, out var timeOnly))
×
537
            return timeOnly;
×
538

539
        if (TimeSpan.TryParse(value, out var timeSpan))
×
540
            return TimeOnly.FromTimeSpan(timeSpan);
×
541

542
        if (DateTime.TryParse(value, out var dateTime))
×
543
            return TimeOnly.FromDateTime(dateTime);
×
544

545
        if (DateTimeOffset.TryParse(value, out var dateTimeOffset))
×
546
            return TimeOnly.FromDateTime(dateTimeOffset.DateTime);
×
547

548
        return null;
×
549
    }
550
#endif
551

552
    /// <summary>
553
    /// Safely converts the specified string input to the given <paramref name="type"/>.
554
    /// Supports all common base types, including nullable types, and returns <c>null</c> for empty or invalid input if the type is nullable.
555
    /// </summary>
556
    /// <param name="type">The target type to convert to.</param>
557
    /// <param name="input">The string input to convert.</param>
558
    /// <returns>
559
    /// The converted value as an object, or <c>null</c> if conversion fails and the type is nullable; otherwise, the default value for the type.
560
    /// </returns>
561
    /// <exception cref="ArgumentNullException">Thrown if <paramref name="type"/> is <c>null</c>.</exception>
562
    public static object? SafeConvert(Type type, string? input)
563
    {
564
        ArgumentNullException.ThrowIfNull(type);
29✔
565

566
        // first try string
567
        if (type == typeof(string))
29✔
568
        {
569
            return input;
10✔
570
        }
571

572
        var isNullable = type.IsNullable();
19✔
573
        if ((input?.IsNullOrEmpty() != false) && isNullable)
19!
574
        {
575
            return null;
4✔
576
        }
577

578
        input = input?.Trim();
15!
579
        var underlyingType = type.GetUnderlyingType();
15✔
580

581
        // convert by type
582
        if (underlyingType == typeof(bool))
15✔
583
        {
584
            return input.ToBoolean();
4✔
585
        }
586
        if (underlyingType == typeof(byte))
11!
587
        {
UNCOV
588
            var value = input.ToByte();
×
589
            return value ?? (isNullable ? null : 0);
×
590
        }
591
        if (underlyingType == typeof(DateTime))
11!
592
        {
UNCOV
593
            var value = input.ToDateTime();
×
594
            return value ?? (isNullable ? null : DateTime.MinValue);
×
595
        }
596
        if (underlyingType == typeof(decimal))
11!
597
        {
UNCOV
598
            var value = input.ToDecimal();
×
599
            return value ?? (isNullable ? null : 0);
×
600
        }
601
        if (underlyingType == typeof(double))
11!
602
        {
UNCOV
603
            var value = input.ToDouble();
×
604
            return value ?? (isNullable ? null : 0);
×
605
        }
606
        if (underlyingType == typeof(short))
11!
607
        {
UNCOV
608
            var value = input.ToInt16();
×
609
            return value ?? (isNullable ? null : 0);
×
610
        }
611
        if (underlyingType == typeof(int))
11✔
612
        {
613
            var value = input.ToInt32();
3✔
614
            return value ?? (isNullable ? null : 0);
3!
615
        }
616
        if (underlyingType == typeof(long))
8!
617
        {
UNCOV
618
            var value = input.ToInt64();
×
619
            return value ?? (isNullable ? null : 0);
×
620
        }
621
        if (underlyingType == typeof(float))
8!
622
        {
UNCOV
623
            var value = input.ToSingle();
×
624
            return value ?? (isNullable ? null : 0);
×
625
        }
626
        if (underlyingType == typeof(ushort))
8!
627
        {
UNCOV
628
            var value = input.ToUInt16();
×
629
            return value ?? (isNullable ? null : 0);
×
630
        }
631
        if (underlyingType == typeof(uint))
8!
632
        {
UNCOV
633
            var value = input.ToUInt32();
×
634
            return value ?? (isNullable ? null : 0);
×
635
        }
636
        if (underlyingType == typeof(ulong))
8!
637
        {
UNCOV
638
            var value = input.ToUInt64();
×
639
            return value ?? (isNullable ? null : 0);
×
640
        }
641
        if (underlyingType == typeof(TimeSpan))
8!
642
        {
UNCOV
643
            var value = input.ToTimeSpan();
×
644
            return value ?? (isNullable ? null : TimeSpan.Zero);
×
645
        }
646
        if (underlyingType == typeof(Guid))
8✔
647
        {
648
            var value = input.ToGuid();
5✔
649
            return value ?? (isNullable ? null : Guid.Empty);
5!
650
        }
651
#if NET6_0_OR_GREATER
652
        if (underlyingType == typeof(DateOnly))
3!
653
        {
654
            var value = input.ToDateOnly();
3✔
655
            return value ?? (isNullable ? null : DateOnly.MinValue);
3!
656
        }
UNCOV
657
        if (underlyingType == typeof(TimeOnly))
×
658
        {
UNCOV
659
            var value = input.ToTimeOnly();
×
660
            return value ?? (isNullable ? null : TimeOnly.MinValue);
×
661
        }
662
#endif
UNCOV
663
        return default;
×
664
    }
665

666
    /// <summary>
667
    /// Converts the specified result object to the given <typeparamref name="TValue"/> type.
668
    /// Supports custom conversion functions and safe conversion from string or other types.
669
    /// </summary>
670
    /// <typeparam name="TValue">The target type to convert to.</typeparam>
671
    /// <param name="result">The result object to convert.</param>
672
    /// <param name="convert">An optional custom conversion function.</param>
673
    /// <returns>
674
    /// The converted value as <typeparamref name="TValue"/>, or the default value if conversion fails.
675
    /// </returns>
676
    public static TValue? ConvertValue<TValue>(object? result, Func<object?, TValue>? convert = null)
677
    {
678
        if (result is null || result == DBNull.Value)
60!
679
            return default;
3✔
680

681
        if (result is TValue valueType)
57✔
682
            return valueType;
42✔
683

684
        if (convert != null)
15!
UNCOV
685
            return convert(result);
×
686

687
        if (result is string stringValue)
15✔
688
            return (TValue?)SafeConvert(typeof(TValue), stringValue);
5✔
689

690
        try
691
        {
692
            return (TValue)Convert.ChangeType(result, typeof(TValue));
10✔
693
        }
UNCOV
694
        catch
×
695
        {
UNCOV
696
            return default;
×
697
        }
698
    }
10✔
699
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc