Skip to content

Commit 20c36ba

Browse files
committed
finish nullable
1 parent cfc8340 commit 20c36ba

File tree

6 files changed

+377
-341
lines changed

6 files changed

+377
-341
lines changed

Arrays.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,12 @@ internal set
184184
if (elem == null) continue;
185185
if (elem.Owner == null)
186186
{
187-
Inner[i] = OwnerDatamodel.ImportElement(elem, Datamodel.ImportRecursionMode.Stubs, Datamodel.ImportOverwriteMode.Stubs);
187+
var importedElement = OwnerDatamodel.ImportElement(elem, Datamodel.ImportRecursionMode.Stubs, Datamodel.ImportOverwriteMode.Stubs);
188+
189+
if(importedElement is not null)
190+
{
191+
Inner[i] = importedElement;
192+
}
188193
}
189194
else if (elem.Owner != OwnerDatamodel)
190195
throw new ElementOwnershipException();
@@ -198,9 +203,18 @@ protected override void Insert_Internal(int index, Element item)
198203
if (item != null && OwnerDatamodel != null)
199204
{
200205
if (item.Owner == null)
201-
item = OwnerDatamodel.ImportElement(item, Datamodel.ImportRecursionMode.Recursive, Datamodel.ImportOverwriteMode.Stubs);
206+
{
207+
var importedElement = OwnerDatamodel.ImportElement(item, Datamodel.ImportRecursionMode.Recursive, Datamodel.ImportOverwriteMode.Stubs);
208+
209+
if(importedElement is not null)
210+
{
211+
item = importedElement;
212+
}
213+
}
202214
else if (item.Owner != OwnerDatamodel)
215+
{
203216
throw new ElementOwnershipException();
217+
}
204218
}
205219

206220
base.Insert_Internal(index, item!);
@@ -215,7 +229,7 @@ public override Element this[int index]
215229
{
216230
try
217231
{
218-
elem = Inner[index] = elem.Owner.OnStubRequest(elem.ID);
232+
elem = Inner[index] = elem.Owner.OnStubRequest(elem.ID)!;
219233
}
220234
catch (Exception err)
221235
{

Attribute.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public AttributeList.OverrideType? OverrideType
8484
/// <summary>
8585
/// Gets the <see cref="AttributeList"/> which this Attribute is a member of.
8686
/// </summary>
87-
public AttributeList Owner
87+
public AttributeList? Owner
8888
{
8989
get { return _Owner; }
9090
internal set
@@ -95,9 +95,9 @@ internal set
9595
_Owner = value;
9696
}
9797
}
98-
AttributeList _Owner;
98+
AttributeList? _Owner;
9999

100-
Datamodel? OwnerDatamodel { get { return Owner.Owner; } }
100+
Datamodel? OwnerDatamodel { get { return Owner?.Owner; } }
101101

102102
/// <summary>
103103
/// Gets whether the value of this Attribute has yet to be decoded.
@@ -125,7 +125,7 @@ public void DeferredLoad()
125125
}
126126
catch (Exception err)
127127
{
128-
throw new CodecException($"Deferred loading of attribute \"{Name}\" on element {((Element)Owner).ID} using {OwnerDatamodel.Codec} codec threw an exception.", err);
128+
throw new CodecException($"Deferred loading of attribute \"{Name}\" on element {((Element?)Owner)?.ID} using {OwnerDatamodel.Codec} codec threw an exception.", err);
129129
}
130130
Offset = 0;
131131

AttributeList.cs

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using System.Linq;
88
using System.Numerics;
99

10-
using AttrKVP = System.Collections.Generic.KeyValuePair<string, object>;
10+
using AttrKVP = System.Collections.Generic.KeyValuePair<string, object?>;
1111
using System.Reflection;
1212
using System.IO;
1313

@@ -18,7 +18,7 @@ namespace Datamodel
1818
/// </summary>
1919
[DebuggerTypeProxy(typeof(DebugView))]
2020
[DebuggerDisplay("Count = {Count}")]
21-
public class AttributeList : IDictionary<string, object>, IDictionary
21+
public class AttributeList : IDictionary<string, object?>, IDictionary
2222
{
2323
internal OrderedDictionary PropertyInfos;
2424
internal OrderedDictionary Inner;
@@ -29,6 +29,11 @@ private ICollection<Attribute> GetPropertyBasedAttributes(bool useSerializationN
2929
var result = new List<Attribute>();
3030
foreach (DictionaryEntry entry in PropertyInfos)
3131
{
32+
if(entry.Value is null)
33+
{
34+
throw new InvalidDataException("Property value can not be null");
35+
}
36+
3237
var prop = (PropertyInfo)entry.Value;
3338
var name = useSerializationName ? (string)entry.Key : prop.Name;
3439
var attr = new Attribute(name, this, prop.GetValue(this));
@@ -64,7 +69,7 @@ public DebugAttribute(Attribute attr)
6469
readonly Attribute Attr;
6570

6671
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
67-
object Value { get { return Attr.Value; } }
72+
object? Value { get { return Attr.Value; } }
6873
}
6974
}
7075

@@ -109,7 +114,7 @@ public AttributeList(Datamodel? owner)
109114
/// </summary>
110115
/// <param name="key">The name of the attribute. Must be unique to this AttributeList.</param>
111116
/// <param name="value">The value of the Attribute. Must be of a valid Datamodel type.</param>
112-
public void Add(string key, object value)
117+
public void Add(string key, object? value)
113118
{
114119
this[key] = value;
115120
}
@@ -128,7 +133,14 @@ public void Add(string key, object value)
128133
/// <exception cref="KeyNotFoundException">Thrown when the given attribute is not present in the list.</exception>
129134
public OverrideType? GetOverrideType(string key)
130135
{
131-
return ((Attribute)Inner[key]).OverrideType;
136+
var attrib = Inner[key];
137+
138+
if(attrib is null)
139+
{
140+
return null;
141+
}
142+
143+
return ((Attribute)attrib).OverrideType;
132144
}
133145

134146
/// <summary>
@@ -139,7 +151,13 @@ public void Add(string key, object value)
139151
/// <exception cref="AttributeTypeException">Thrown when the attribute's CLR type does not map to the value given in <paramref name="type"/>.</exception>
140152
public void SetOverrideType(string key, OverrideType? type)
141153
{
142-
((Attribute)Inner[key]).OverrideType = type;
154+
var attrib = Inner[key];
155+
156+
if (attrib is not null)
157+
{
158+
((Attribute)attrib).OverrideType = type;
159+
}
160+
143161
}
144162

145163
/// <summary>
@@ -162,7 +180,7 @@ public bool Remove(string key)
162180
{
163181
lock (Attribute_ChangeLock)
164182
{
165-
var attr = (Attribute)Inner[key];
183+
var attr = (Attribute?)Inner[key];
166184
if (attr == null) return false;
167185

168186
var index = IndexOf(key);
@@ -172,11 +190,11 @@ public bool Remove(string key)
172190
}
173191
}
174192

175-
public bool TryGetValue(string key, out object value)
193+
public bool TryGetValue(string key, out object? value)
176194
{
177-
Attribute result;
195+
Attribute? result;
178196
lock (Attribute_ChangeLock)
179-
result = (Attribute)Inner[key];
197+
result = (Attribute?)Inner[key];
180198

181199
if (result != null)
182200
{
@@ -200,7 +218,7 @@ public ICollection<string> Keys
200218
{
201219
get { lock (Attribute_ChangeLock) return Inner.Keys.Cast<string>().ToArray(); }
202220
}
203-
public ICollection<object> Values
221+
public ICollection<object?> Values
204222
{
205223
get { lock (Attribute_ChangeLock) return Inner.Values.Cast<Attribute>().Select(attr => attr.Value).ToArray(); }
206224
}
@@ -223,7 +241,7 @@ public virtual object? this[string name]
223241
var attr = (Attribute?)Inner[name];
224242
if (attr == null)
225243
{
226-
var prop_attr = (PropertyInfo)PropertyInfos[name];
244+
var prop_attr = (PropertyInfo?)PropertyInfos[name];
227245
if (prop_attr != null)
228246
{
229247
return prop_attr.GetValue(this);
@@ -238,16 +256,16 @@ public virtual object? this[string name]
238256
{
239257
ArgumentNullException.ThrowIfNull(name);
240258
if (value != null && !Datamodel.IsDatamodelType(value.GetType()))
241-
throw new AttributeTypeException(String.Format("{0} is not a valid Datamodel attribute type. (If this is an array, it must implement IList<T>).", value.GetType().FullName));
259+
throw new AttributeTypeException($"{value.GetType().FullName} is not a valid Datamodel attribute type. (If this is an array, it must implement IList<T>).");
242260

243-
if (Owner != null && this == Owner.PrefixAttributes && value.GetType() == typeof(Element))
261+
if (Owner != null && this == Owner.PrefixAttributes && value?.GetType() == typeof(Element))
244262
throw new AttributeTypeException("Elements are not supported as prefix attributes.");
245263

246-
var prop_attr = (PropertyInfo)PropertyInfos[name];
264+
var prop_attr = (PropertyInfo?)PropertyInfos[name];
247265

248266
if (prop_attr != null)
249267
{
250-
PropertyInfo prop = GetType().GetProperty(prop_attr.Name, BindingFlags.Public | BindingFlags.Instance);
268+
PropertyInfo? prop = GetType().GetProperty(prop_attr.Name, BindingFlags.Public | BindingFlags.Instance);
251269

252270
if (prop != null && prop.CanWrite)
253271
{
@@ -272,12 +290,12 @@ public virtual object? this[string name]
272290
return;
273291
}
274292

275-
Attribute old_attr;
276-
Attribute new_attr;
293+
Attribute? old_attr;
294+
Attribute? new_attr;
277295
int old_index = -1;
278296
lock (Attribute_ChangeLock)
279297
{
280-
old_attr = (Attribute)Inner[name];
298+
old_attr = (Attribute?)Inner[name];
281299
new_attr = new Attribute(name, this, value);
282300

283301
if (old_attr != null)
@@ -305,7 +323,13 @@ public AttrKVP this[int index]
305323
{
306324
get
307325
{
308-
var attr = (Attribute)Inner[index];
326+
var attr = (Attribute?)Inner[index];
327+
328+
if(attr is null)
329+
{
330+
throw new InvalidOperationException($"attribute at index {index} doesn't exist");
331+
}
332+
309333
return attr.ToKeyValuePair();
310334
}
311335
set
@@ -320,12 +344,16 @@ public AttrKVP this[int index]
320344
/// </summary>
321345
public void RemoveAt(int index)
322346
{
323-
Attribute attr;
347+
Attribute? attr;
324348
lock (Attribute_ChangeLock)
325349
{
326-
attr = (Attribute)Inner[index];
327-
attr.Owner = null;
328-
Inner.RemoveAt(index);
350+
attr = (Attribute?)Inner[index];
351+
352+
if(attr is not null)
353+
{
354+
attr.Owner = null;
355+
Inner.RemoveAt(index);
356+
}
329357
}
330358
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, attr, index));
331359
}
@@ -398,7 +426,7 @@ IEnumerator IEnumerable.GetEnumerator()
398426
/// Raised when <see cref="Element.Name"/>, <see cref="Element.ClassName"/>, <see cref="Element.ID"/> or
399427
/// a custom Element property has changed.
400428
/// </summary>
401-
public event PropertyChangedEventHandler PropertyChanged;
429+
public event PropertyChangedEventHandler? PropertyChanged;
402430
protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName()] string property = "")
403431
{
404432
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
@@ -407,7 +435,7 @@ protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.Caller
407435
/// <summary>
408436
/// Raised when an <see cref="Attribute"/> is added, removed, or replaced.
409437
/// </summary>
410-
public event NotifyCollectionChangedEventHandler CollectionChanged;
438+
public event NotifyCollectionChangedEventHandler? CollectionChanged;
411439
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
412440
{
413441
Debug.Assert(!(e.NewItems != null && e.NewItems.OfType<Attribute>().Any()) && !(e.OldItems != null && e.OldItems.OfType<Attribute>().Any()));
@@ -437,12 +465,12 @@ void IDictionary.Remove(object key)
437465
Remove((string)key);
438466
}
439467

440-
void IDictionary.Add(object key, object value)
468+
void IDictionary.Add(object key, object? value)
441469
{
442470
Add((string)key, value);
443471
}
444472

445-
object IDictionary.this[object key]
473+
object? IDictionary.this[object key]
446474
{
447475
get
448476
{
@@ -466,7 +494,7 @@ bool ICollection<AttrKVP>.Remove(AttrKVP item)
466494
{
467495
lock (Attribute_ChangeLock)
468496
{
469-
var attr = (Attribute)Inner[item.Key];
497+
var attr = (Attribute?)Inner[item.Key];
470498
if (attr == null || attr.Value != item.Value) return false;
471499
Remove(attr.Name);
472500
return true;
@@ -497,7 +525,7 @@ bool ICollection<AttrKVP>.Contains(AttrKVP item)
497525
{
498526
lock (Attribute_ChangeLock)
499527
{
500-
var attr = (Attribute)Inner[item.Key];
528+
var attr = (Attribute?)Inner[item.Key];
501529
return attr != null && attr.Value == item.Value;
502530
}
503531
}
@@ -521,12 +549,17 @@ public static ValueComparer Default
521549
return _Default;
522550
}
523551
}
524-
static ValueComparer _Default;
552+
static ValueComparer? _Default;
525553

526-
public new bool Equals(object x, object y)
554+
public new bool Equals(object? x, object? y)
527555
{
528-
var type_x = x?.GetType();
529-
var type_y = y?.GetType();
556+
if(x is null || y is null)
557+
{
558+
return false;
559+
}
560+
561+
var type_x = x.GetType();
562+
var type_y = y.GetType();
530563

531564
if (type_x == null && type_y == null)
532565
return true;

0 commit comments

Comments
 (0)