-
Notifications
You must be signed in to change notification settings - Fork 453
/
DefaultValue.cs
127 lines (108 loc) · 3.61 KB
/
DefaultValue.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using System;
using System.Collections.Concurrent;
using System.Linq;
using JetBrains.Annotations;
namespace LinqToDB.Common
{
using Extensions;
using Internal;
using Mapping;
/// <summary>
/// Default value provider.
/// Default value used for mapping from NULL database value to C# value.
/// </summary>
[PublicAPI]
public static class DefaultValue
{
static DefaultValue()
{
_values[typeof(int)] = default(int);
_values[typeof(uint)] = default(uint);
_values[typeof(byte)] = default(byte);
_values[typeof(char)] = default(char);
_values[typeof(bool)] = default(bool);
_values[typeof(sbyte)] = default(sbyte);
_values[typeof(short)] = default(short);
_values[typeof(long)] = default(long);
_values[typeof(ushort)] = default(ushort);
_values[typeof(ulong)] = default(ulong);
_values[typeof(float)] = default(float);
_values[typeof(double)] = default(double);
_values[typeof(decimal)] = default(decimal);
_values[typeof(DateTime)] = default(DateTime);
_values[typeof(TimeSpan)] = default(TimeSpan);
_values[typeof(DateTimeOffset)] = default(DateTimeOffset);
_values[typeof(Guid)] = default(Guid);
_values[typeof(string)] = default(string);
}
static readonly ConcurrentDictionary<Type,object?> _values = new ConcurrentDictionary<Type,object?>();
/// <summary>
/// Returns default value for provided type.
/// </summary>
/// <param name="type">Type, for which default value requested.</param>
/// <param name="mappingSchema">Optional mapping schema to provide mapping information for enum type.</param>
/// <returns>Default value for specific type.</returns>
public static object? GetValue(Type type, MappingSchema? mappingSchema = null)
{
if (type == null) throw new ArgumentNullException(nameof(type));
var ms = mappingSchema ?? MappingSchema.Default;
if (_values.TryGetValue(type, out var value))
return value;
if (type.IsEnum)
{
var mapValues = ms.GetMapValues(type);
if (mapValues != null)
{
var fields =
from f in mapValues
where f.MapValues.Any(a => a.Value == null)
select f.OrigValue;
value = fields.FirstOrDefault();
}
}
if (value == null && !type.IsNullableType())
value = ReflectionExtensions.GetDefaultValue(type);
_values[type] = value;
return value;
}
/// <summary>
/// Returns default value for provided type.
/// </summary>
/// <typeparam name="T">Type, for which default value requested.</typeparam>
/// <returns>Default value for specific type.</returns>
public static T GetValue<T>()
{
if (_values.TryGetValue(typeof(T), out var value))
return (T)value!;
_values[typeof(T)] = default(T)!;
return default(T)!;
}
/// <summary>
/// Sets default value for provided type.
/// </summary>
/// <typeparam name="T">Type, for which default value set.</typeparam>
/// <param name="value">Default value for specific type.</param>
public static void SetValue<T>(T value)
{
_values[typeof(T)] = value;
}
}
/// <summary>
/// Default value provider for specific type.
/// Default value used for mapping from NULL database value to C# value.
/// </summary>
/// <typeparam name="T">Type parameter.</typeparam>
[PublicAPI]
public static class DefaultValue<T>
{
static T _value = DefaultValue.GetValue<T>();
/// <summary>
/// Gets or sets default value for specific type.
/// </summary>
public static T Value
{
get => _value;
set => DefaultValue.SetValue(_value = value);
}
}
}