diff --git a/Kyoo.Common/Utility/Merger.cs b/Kyoo.Common/Utility/Merger.cs
index 1918ba41..3c2d6247 100644
--- a/Kyoo.Common/Utility/Merger.cs
+++ b/Kyoo.Common/Utility/Merger.cs
@@ -44,22 +44,89 @@ namespace Kyoo
/// The second dictionary to merge
/// The type of the keys in dictionaries
/// The type of values in the dictionaries
- /// A dictionary containing the result of the merge.
+ /// The first dictionary with the missing elements of .
+ ///
[ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
public static IDictionary MergeDictionaries([CanBeNull] IDictionary first,
[CanBeNull] IDictionary second)
+ {
+ return MergeDictionaries(first, second, out bool _);
+ }
+
+ ///
+ /// Merge two dictionary, if the same key is found on both dictionary, the values of the first one is kept.
+ ///
+ /// The first dictionary to merge
+ /// The second dictionary to merge
+ ///
+ /// true if a new items has been added to the dictionary, false otherwise.
+ ///
+ /// The type of the keys in dictionaries
+ /// The type of values in the dictionaries
+ /// The first dictionary with the missing elements of .
+ [ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
+ public static IDictionary MergeDictionaries([CanBeNull] IDictionary first,
+ [CanBeNull] IDictionary second,
+ out bool hasChanged)
{
if (first == null)
+ {
+ hasChanged = true;
return second;
+ }
+
+ hasChanged = false;
if (second == null)
return first;
- Dictionary merged = new();
- merged.EnsureCapacity(first.Count + second.Count);
- foreach ((T key, T2 value) in first)
- merged.Add(key, value);
foreach ((T key, T2 value) in second)
- merged.TryAdd(key, value);
- return merged;
+ hasChanged |= first.TryAdd(key, value);
+ return first;
+ }
+
+ ///
+ /// Merge two dictionary, if the same key is found on both dictionary, the values of the second one is kept.
+ ///
+ ///
+ /// The only difference in this function compared to
+ ///
+ /// is the way is calculated and the order of the arguments.
+ ///
+ /// MergeDictionaries(first, second);
+ ///
+ /// will do the same thing as
+ ///
+ /// CompleteDictionaries(second, first, out bool _);
+ ///
+ ///
+ /// The first dictionary to merge
+ /// The second dictionary to merge
+ ///
+ /// true if a new items has been added to the dictionary, false otherwise.
+ ///
+ /// The type of the keys in dictionaries
+ /// The type of values in the dictionaries
+ ///
+ /// A dictionary with the missing elements of
+ /// set to those of .
+ ///
+ [ContractAnnotation("first:notnull => notnull; second:notnull => notnull", true)]
+ public static IDictionary CompleteDictionaries([CanBeNull] IDictionary first,
+ [CanBeNull] IDictionary second,
+ out bool hasChanged)
+ {
+ if (first == null)
+ {
+ hasChanged = true;
+ return second;
+ }
+
+ hasChanged = false;
+ if (second == null)
+ return first;
+ hasChanged = second.Any(x => !x.Value.Equals(first[x.Key]));
+ foreach ((T key, T2 value) in first)
+ second.TryAdd(key, value);
+ return second;
}
///
@@ -91,7 +158,9 @@ namespace Kyoo
///
/// Set every non-default values of seconds to the corresponding property of second.
/// Dictionaries are handled like anonymous objects with a property per key/pair value
- /// (see for more details).
+ /// (see
+ ///
+ /// for more details).
/// At the end, the OnMerge method of first will be called if first is a
///
///
@@ -135,17 +204,24 @@ namespace Kyoo
object defaultValue = property.GetCustomAttribute()?.Value
?? property.PropertyType.GetClrDefault();
- if (value?.Equals(defaultValue) != false || value == property.GetValue(first))
+ if (value?.Equals(defaultValue) != false || value.Equals(property.GetValue(first)))
continue;
if (Utility.IsOfGenericType(property.PropertyType, typeof(IDictionary<,>)))
{
Type[] dictionaryTypes = Utility.GetGenericDefinition(property.PropertyType, typeof(IDictionary<,>))
.GenericTypeArguments;
- property.SetValue(first, Utility.RunGenericMethod