Skip to content

Commit f9e5fa4

Browse files
committed
Added nullable to FastDynamicObject.
1 parent 7dbb3fe commit f9e5fa4

File tree

2 files changed

+115
-116
lines changed

2 files changed

+115
-116
lines changed

src/CsvHelper/FastDynamicObject.cs

+21-22
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,22 @@
33
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
44
// https://github.com/JoshClose/CsvHelper
55
using System.Collections;
6-
using System.Diagnostics.CodeAnalysis;
76
using System.Dynamic;
87
using System.Linq.Expressions;
98
using System.Reflection;
109

1110
namespace CsvHelper;
1211

13-
internal class FastDynamicObject : IDynamicMetaObjectProvider, IDictionary<string, object>
12+
internal class FastDynamicObject : IDynamicMetaObjectProvider, IDictionary<string, object?>
1413
{
15-
private readonly Dictionary<string, object> dict;
14+
private readonly Dictionary<string, object?> dict;
1615

1716
public FastDynamicObject()
1817
{
19-
dict = new Dictionary<string, object>();
18+
dict = new Dictionary<string, object?>();
2019
}
2120

22-
object IDictionary<string, object>.this[string key]
21+
object? IDictionary<string, object?>.this[string key]
2322
{
2423
get
2524
{
@@ -37,15 +36,15 @@ object IDictionary<string, object>.this[string key]
3736
}
3837
}
3938

40-
ICollection<string> IDictionary<string, object>.Keys => dict.Keys;
39+
ICollection<string> IDictionary<string, object?>.Keys => dict.Keys;
4140

42-
ICollection<object> IDictionary<string, object>.Values => dict.Values;
41+
ICollection<object?> IDictionary<string, object?>.Values => dict.Values;
4342

44-
int ICollection<KeyValuePair<string, object>>.Count => dict.Count;
43+
int ICollection<KeyValuePair<string, object?>>.Count => dict.Count;
4544

46-
bool ICollection<KeyValuePair<string, object>>.IsReadOnly => false;
45+
bool ICollection<KeyValuePair<string, object?>>.IsReadOnly => false;
4746

48-
object SetValue(string key, object value)
47+
object? SetValue(string key, object? value)
4948
{
5049
dict[key] = value;
5150

@@ -57,32 +56,32 @@ DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
5756
return new FastDynamicMetaObject(parameter, BindingRestrictions.Empty, this);
5857
}
5958

60-
void IDictionary<string, object>.Add(string key, object value)
59+
void IDictionary<string, object?>.Add(string key, object? value)
6160
{
6261
SetValue(key, value);
6362
}
6463

65-
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
64+
void ICollection<KeyValuePair<string, object?>>.Add(KeyValuePair<string, object?> item)
6665
{
6766
SetValue(item.Key, item.Value);
6867
}
6968

70-
void ICollection<KeyValuePair<string, object>>.Clear()
69+
void ICollection<KeyValuePair<string, object?>>.Clear()
7170
{
7271
dict.Clear();
7372
}
7473

75-
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
74+
bool ICollection<KeyValuePair<string, object?>>.Contains(KeyValuePair<string, object?> item)
7675
{
7776
return dict.Contains(item);
7877
}
7978

80-
bool IDictionary<string, object>.ContainsKey(string key)
79+
bool IDictionary<string, object?>.ContainsKey(string key)
8180
{
8281
return dict.ContainsKey(key);
8382
}
8483

85-
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
84+
void ICollection<KeyValuePair<string, object?>>.CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex)
8685
{
8786
if (arrayIndex < 0 || arrayIndex >= array.Length)
8887
{
@@ -102,7 +101,7 @@ void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, objec
102101
}
103102
}
104103

105-
IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
104+
IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator()
106105
{
107106
return dict.GetEnumerator();
108107
}
@@ -112,24 +111,24 @@ IEnumerator IEnumerable.GetEnumerator()
112111
return dict.GetEnumerator();
113112
}
114113

115-
bool IDictionary<string, object>.Remove(string key)
114+
bool IDictionary<string, object?>.Remove(string key)
116115
{
117116
return dict.Remove(key);
118117
}
119118

120-
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
119+
bool ICollection<KeyValuePair<string, object?>>.Remove(KeyValuePair<string, object?> item)
121120
{
122121
return dict.Remove(item.Key);
123122
}
124123

125-
bool IDictionary<string, object>.TryGetValue(string key, out object value)
124+
bool IDictionary<string, object?>.TryGetValue(string key, out object? value)
126125
{
127126
return dict.TryGetValue(key, out value!);
128127
}
129128

130129
private class FastDynamicMetaObject : DynamicMetaObject
131130
{
132-
private static readonly MethodInfo getValueMethod = typeof(IDictionary<string, object>).GetProperty("Item")!.GetGetMethod()!;
131+
private static readonly MethodInfo getValueMethod = typeof(IDictionary<string, object?>).GetProperty("Item")!.GetGetMethod()!;
133132
private static readonly MethodInfo setValueMethod = typeof(FastDynamicObject).GetMethod("SetValue", BindingFlags.NonPublic | BindingFlags.Instance)!;
134133

135134
public FastDynamicMetaObject(Expression expression, BindingRestrictions restrictions) : base(expression, restrictions) { }
@@ -165,7 +164,7 @@ public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, Dy
165164

166165
public override IEnumerable<string> GetDynamicMemberNames()
167166
{
168-
if (HasValue && Value is IDictionary<string, object> lookup)
167+
if (HasValue && Value is IDictionary<string, object?> lookup)
169168
{
170169
return lookup.Keys;
171170
}
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,99 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using Xunit;
1+
using Xunit;
42

5-
namespace CsvHelper.Tests.Dynamic
3+
namespace CsvHelper.Tests.Dynamic;
4+
5+
public class FastDynamicObjectTests
66
{
7-
public class FastDynamicObjectTests
7+
[Fact]
8+
public void Dynamic_SetAndGet_Works()
9+
{
10+
dynamic obj = new FastDynamicObject();
11+
obj.Id = 1;
12+
obj.Name = "one";
13+
obj.Null = null;
14+
15+
var id = obj.Id;
16+
var name = obj.Name;
17+
var @null = obj.Null;
18+
19+
Assert.Equal(1, id);
20+
Assert.Equal("one", name);
21+
Assert.Null(@null);
22+
}
23+
24+
[Fact]
25+
public void CopyTo_NegativeIndex_Throws()
26+
{
27+
IDictionary<string, object?> d = new FastDynamicObject();
28+
var a = new KeyValuePair<string, object?>[1];
29+
30+
Assert.Throws<ArgumentOutOfRangeException>(() => d.CopyTo(a, -1));
31+
}
32+
33+
[Fact]
34+
public void CopyTo_IndexLargerThanArrayLength_Throws()
35+
{
36+
IDictionary<string, object?> d = new FastDynamicObject();
37+
var a = new KeyValuePair<string, object?>[1];
38+
39+
Assert.Throws<ArgumentOutOfRangeException>(() => d.CopyTo(a, a.Length));
40+
}
41+
42+
[Fact]
43+
public void CopyTo_SourceIsLargerThanDestination_Throws()
44+
{
45+
IDictionary<string, object?> d = new FastDynamicObject();
46+
d["a"] = 1;
47+
d["b"] = 2;
48+
var a = new KeyValuePair<string, object?>[1];
49+
50+
Assert.Throws<ArgumentException>(() => d.CopyTo(a, 0));
51+
}
52+
53+
[Fact]
54+
public void CopyTo_IndexGreaterThanZeroAndSourceIsLargerThanDestination_Throws()
55+
{
56+
IDictionary<string, object?> d = new FastDynamicObject();
57+
d["a"] = 1;
58+
d["b"] = 2;
59+
var a = new KeyValuePair<string, object?>[2];
60+
61+
Assert.Throws<ArgumentException>(() => d.CopyTo(a, 1));
62+
}
63+
64+
[Fact]
65+
public void CopyTo_StartAtZero_Copies()
66+
{
67+
IDictionary<string, object?> d = new FastDynamicObject();
68+
d["a"] = 1;
69+
d["b"] = 2;
70+
var a = new KeyValuePair<string, object?>[2];
71+
72+
d.CopyTo(a, 0);
73+
74+
Assert.Equal("a", a[0].Key);
75+
Assert.Equal(1, a[0].Value);
76+
Assert.Equal("b", a[1].Key);
77+
Assert.Equal(2, a[1].Value);
78+
}
79+
80+
[Fact]
81+
public void CopyTo_StartGreaterThanZero_Copies()
882
{
9-
[Fact]
10-
public void Dynamic_SetAndGet_Works()
11-
{
12-
dynamic obj = new FastDynamicObject();
13-
obj.Id = 1;
14-
obj.Name = "one";
15-
16-
var id = obj.Id;
17-
var name = obj.Name;
18-
19-
Assert.Equal(1, id);
20-
Assert.Equal("one", name);
21-
}
22-
23-
[Fact]
24-
public void CopyTo_NegativeIndex_Throws()
25-
{
26-
IDictionary<string, object> d = new FastDynamicObject();
27-
var a = new KeyValuePair<string, object>[1];
28-
29-
Assert.Throws<ArgumentOutOfRangeException>(() => d.CopyTo(a, -1));
30-
}
31-
32-
[Fact]
33-
public void CopyTo_IndexLargerThanArrayLength_Throws()
34-
{
35-
IDictionary<string, object> d = new FastDynamicObject();
36-
var a = new KeyValuePair<string, object>[1];
37-
38-
Assert.Throws<ArgumentOutOfRangeException>(() => d.CopyTo(a, a.Length));
39-
}
40-
41-
[Fact]
42-
public void CopyTo_SourceIsLargerThanDestination_Throws()
43-
{
44-
IDictionary<string, object> d = new FastDynamicObject();
45-
d["a"] = 1;
46-
d["b"] = 2;
47-
var a = new KeyValuePair<string, object>[1];
48-
49-
Assert.Throws<ArgumentException>(() => d.CopyTo(a, 0));
50-
}
51-
52-
[Fact]
53-
public void CopyTo_IndexGreaterThanZeroAndSourceIsLargerThanDestination_Throws()
54-
{
55-
IDictionary<string, object> d = new FastDynamicObject();
56-
d["a"] = 1;
57-
d["b"] = 2;
58-
var a = new KeyValuePair<string, object>[2];
59-
60-
Assert.Throws<ArgumentException>(() => d.CopyTo(a, 1));
61-
}
62-
63-
[Fact]
64-
public void CopyTo_StartAtZero_Copies()
65-
{
66-
IDictionary<string, object> d = new FastDynamicObject();
67-
d["a"] = 1;
68-
d["b"] = 2;
69-
var a = new KeyValuePair<string, object>[2];
70-
71-
d.CopyTo(a, 0);
72-
73-
Assert.Equal("a", a[0].Key);
74-
Assert.Equal(1, a[0].Value);
75-
Assert.Equal("b", a[1].Key);
76-
Assert.Equal(2, a[1].Value);
77-
}
78-
79-
[Fact]
80-
public void CopyTo_StartGreaterThanZero_Copies()
81-
{
82-
IDictionary<string, object> d = new FastDynamicObject();
83-
d["a"] = 1;
84-
d["b"] = 2;
85-
var a = new KeyValuePair<string, object>[4];
86-
87-
d.CopyTo(a, 1);
88-
89-
Assert.Null(a[0].Key);
90-
Assert.Null(a[0].Value);
91-
Assert.Equal("a", a[1].Key);
92-
Assert.Equal(1, a[1].Value);
93-
Assert.Equal("b", a[2].Key);
94-
Assert.Equal(2, a[2].Value);
95-
Assert.Null(a[3].Key);
96-
Assert.Null(a[3].Value);
97-
}
83+
IDictionary<string, object?> d = new FastDynamicObject();
84+
d["a"] = 1;
85+
d["b"] = 2;
86+
var a = new KeyValuePair<string, object?>[4];
87+
88+
d.CopyTo(a, 1);
89+
90+
Assert.Null(a[0].Key);
91+
Assert.Null(a[0].Value);
92+
Assert.Equal("a", a[1].Key);
93+
Assert.Equal(1, a[1].Value);
94+
Assert.Equal("b", a[2].Key);
95+
Assert.Equal(2, a[2].Value);
96+
Assert.Null(a[3].Key);
97+
Assert.Null(a[3].Value);
9898
}
9999
}

0 commit comments

Comments
 (0)