private static List <T> Copy <T>(List <T> source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((List <T>)existingCopy); } var length = source.Count; var target = new List <T>(length); context.RecordCopy(source, target); for (var i = 0; i < length; i++) { T sourceItem = source[i]; if (sourceItem != null) { target.Add(Cloner <T> .Get(sourceItem, context)); } else { target.Add(sourceItem); } } return(target); }
private static T Copy <T>(T source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((T)existingCopy); } if (!(source is Array sourceAsArray)) { throw new InvalidCastException($"Cannot cast non-array type {source?.GetType()} to Array."); } var elementType = source.GetType().GetElementType(); var rank = sourceAsArray.Rank; var lengths = new int[rank]; for (var i = 0; i < rank; i++) { lengths[i] = sourceAsArray.GetLength(i); } var target = Array.CreateInstance(elementType, lengths); context.RecordCopy(sourceAsArray, target); Array.Copy(sourceAsArray, target, sourceAsArray.Length); return((T)(object)target); }
private static T[,] Copy <T>(T[,] source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((T[, ])existingCopy); } var lenI = source.GetLength(0); var lenJ = source.GetLength(1); var target = new T[lenI, lenJ]; context.RecordCopy(source, target); for (var i = 0; i < lenI; i++) { for (var j = 0; j < lenJ; j++) { T sourceItem = source[i, j]; if (sourceItem != null) { target[i, j] = Cloner <T> .Get(sourceItem, context); } } } return(target); }
public object DeepCopy(object input, CopyContext context) { if (context.TryGetCopy <object>(input, out var result)) { return(result); } ThrowNotNullException(input); return(null); }
/// <summary> /// Creates a deep copy of the provided input. /// </summary> /// <param name="input">The input.</param> /// <param name="context">The context.</param> /// <returns>A copy of <paramref name="input" />.</returns> public static byte[] DeepCopy(byte[] input, CopyContext context) { if (context.TryGetCopy <byte[]>(input, out var result)) { return(result); } result = new byte[input.Length]; context.RecordCopy(input, result); input.CopyTo(result.AsSpan()); return(result); }
private static T[,] Copy <T>(T[,] source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((T[, ])existingCopy); } var result = new T[source.GetLength(0), source.GetLength(1)]; context.RecordCopy(source, result); Array.Copy(source, result, source.Length); return(result); }
/// <inheritdoc/> public TField DeepCopy(TField input, CopyContext context) { if (context.TryGetCopy <TField>(input, out var result)) { return(result); } var surrogate = _converter.ConvertToSurrogate(in input); var copy = _surrogateCopier.DeepCopy(surrogate, context); result = _converter.ConvertFromSurrogate(in copy); context.RecordCopy(input, result); return(result); }
public T[] DeepCopy(T[] input, CopyContext context) { if (context.TryGetCopy <T[]>(input, out var result)) { return(result); } result = new T[input.Length]; context.RecordCopy(input, result); for (var i = 0; i < input.Length; i++) { result[i] = _elementCopier.DeepCopy(input[i], context); } return(result); }
public Tuple <T> DeepCopy(Tuple <T> input, CopyContext context) { if (context.TryGetCopy(input, out Tuple <T> result)) { return(result); } if (input.GetType() != typeof(Tuple <T>)) { return(context.Copy(input)); } result = new Tuple <T>(_copier.DeepCopy(input.Item1, context)); context.RecordCopy(input, result); return(result); }
public Dictionary <X, Y> GetClone(Dictionary <X, Y> source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((Dictionary <X, Y>)existingCopy); } var target = new Dictionary <X, Y>(source.Count, source.Comparer); context.RecordCopy(source, target); foreach (var pair in source) { target.Add(KeyCloner(pair.Key, context), ValueCloner(pair.Value, context)); } return(target); }
public object DeepCopy(object input, CopyContext context) { if (context.TryGetCopy <object>(input, out var result)) { return(result); } var type = input.GetType(); if (type != typeof(object)) { return(context.Copy(input)); } result = new object(); context.RecordCopy(input, result); return(result); }
/// <inheritdoc /> public SortedDictionary <TKey, TValue> DeepCopy(SortedDictionary <TKey, TValue> input, CopyContext context) { if (context.TryGetCopy <SortedDictionary <TKey, TValue> >(input, out var result)) { return(result); } if (input.GetType() != typeof(SortedDictionary <TKey, TValue>)) { return(context.Copy(input)); } result = new SortedDictionary <TKey, TValue>(input.Comparer); context.RecordCopy(input, result); foreach (var pair in input) { result[_keyCopier.DeepCopy(pair.Key, context)] = _valueCopier.DeepCopy(pair.Value, context); } return(result); }
/// <inheritdoc/> public List <T> DeepCopy(List <T> input, CopyContext context) { if (context.TryGetCopy <List <T> >(input, out var result)) { return(result); } if (input.GetType() != typeof(List <T>)) { return(context.DeepCopy(input)); } result = new List <T>(input.Count); context.RecordCopy(input, result); foreach (var item in input) { result.Add(_copier.DeepCopy(item, context)); } return(result); }
/// <inheritdoc /> public SortedSet <T> DeepCopy(SortedSet <T> input, CopyContext context) { if (context.TryGetCopy <SortedSet <T> >(input, out var result)) { return(result); } if (input.GetType() != typeof(SortedSet <T>)) { return(context.Copy(input)); } result = new SortedSet <T>(input.Comparer); context.RecordCopy(input, result); foreach (var element in input) { result.Add(_elementCopier.DeepCopy(element, context)); } return(result); }
/// <inheritdoc/> public NameValueCollection DeepCopy(NameValueCollection input, CopyContext context) { if (context.TryGetCopy <NameValueCollection>(input, out var result)) { return(result); } if (input.GetType() != typeof(NameValueCollection)) { return(context.DeepCopy(input)); } result = new NameValueCollection(input.Count); context.RecordCopy(input, result); for (var i = 0; i < input.Count; i++) { result.Add(input.GetKey(i), input.Get(i)); } return(result); }
public ConcurrentDictionary <TKey, TValue> DeepCopy(ConcurrentDictionary <TKey, TValue> input, CopyContext context) { if (context.TryGetCopy <ConcurrentDictionary <TKey, TValue> >(input, out var result)) { return(result); } if (input.GetType() != typeof(ConcurrentDictionary <TKey, TValue>)) { return(context.Copy(input)); } // Note that this cannot propagate the input's key comparer, since it is not exposed from ConcurrentDictionary. result = new ConcurrentDictionary <TKey, TValue>(); context.RecordCopy(input, result); foreach (var pair in input) { result[_keyCopier.DeepCopy(pair.Key, context)] = _valueCopier.DeepCopy(pair.Value, context); } return(result); }
/// <inheritdoc/> public ConcurrentQueue <T> DeepCopy(ConcurrentQueue <T> input, CopyContext context) { if (context.TryGetCopy <ConcurrentQueue <T> >(input, out var result)) { return(result); } if (input.GetType() != typeof(ConcurrentQueue <T>)) { return(context.Copy(input)); } // Note that this cannot propagate the input's key comparer, since it is not exposed from ConcurrentDictionary. result = new ConcurrentQueue <T>(); context.RecordCopy(input, result); foreach (var item in input) { result.Enqueue(_copier.DeepCopy(item, context)); } return(result); }
public ReadOnlyDictionary <TKey, TValue> DeepCopy(ReadOnlyDictionary <TKey, TValue> input, CopyContext context) { if (context.TryGetCopy <ReadOnlyDictionary <TKey, TValue> >(input, out var result)) { return(result); } if (input.GetType() != typeof(ReadOnlyDictionary <TKey, TValue>)) { return(context.Copy(input)); } var temp = new Dictionary <TKey, TValue>(input.Count); foreach (var pair in input) { temp[_keyCopier.DeepCopy(pair.Key, context)] = _valueCopier.DeepCopy(pair.Value, context); } result = new ReadOnlyDictionary <TKey, TValue>(temp); context.RecordCopy(input, result); return(result); }
private static T[] Copy <T>(T[] source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((T[])existingCopy); } var length = source.Length; var target = new T[length]; context.RecordCopy(source, target); for (var i = 0; i < length; i++) { T sourceItem = source[i]; if (sourceItem != null) { target[i] = Cloner <T> .Get(sourceItem, context); } } return(target); }
/// <inheritdoc/> object IDeepCopier <object> .DeepCopy(object original, CopyContext context) { if (context.TryGetCopy <Array>(original, out var result)) { return(result); } var type = original.GetType(); var originalArray = (Array)original; var elementType = type.GetElementType(); if (ShallowCopyableTypes.Contains(elementType)) { return(originalArray.Clone()); } // We assume that all arrays have lower bound 0. In .NET 4.0, it's hard to create an array with a non-zero lower bound. var rank = originalArray.Rank; var lengths = new int[rank]; for (var i = 0; i < rank; i++) { lengths[i] = originalArray.GetLength(i); } result = Array.CreateInstance(elementType, lengths); context.RecordCopy(original, result); if (rank == 1) { for (var i = 0; i < lengths[0]; i++) { result.SetValue(_elementCopier.DeepCopy(originalArray.GetValue(i), context), i); } } else if (rank == 2) { for (var i = 0; i < lengths[0]; i++) { for (var j = 0; j < lengths[1]; j++) { result.SetValue(_elementCopier.DeepCopy(originalArray.GetValue(i, j), context), i, j); } } } else { var index = new int[rank]; var sizes = new int[rank]; sizes[rank - 1] = 1; for (var k = rank - 2; k >= 0; k--) { sizes[k] = sizes[k + 1] * lengths[k + 1]; } for (var i = 0; i < originalArray.Length; i++) { int k = i; for (int n = 0; n < rank; n++) { int offset = k / sizes[n]; k -= offset * sizes[n]; index[n] = offset; } result.SetValue(_elementCopier.DeepCopy(originalArray.GetValue(index), context), index); } } return(result); }
private static T Copy <T>(T source, CopyContext context) { if (context.TryGetCopy(source, out var existingCopy)) { return((T)existingCopy); } if (!(source is Array sourceAsArray)) { throw new InvalidCastException($"Cannot cast non-array type {source?.GetType()} to Array."); } var elementType = source.GetType().GetElementType(); var rank = sourceAsArray.Rank; var lengths = new int[rank]; for (var i = 0; i < rank; i++) { lengths[i] = sourceAsArray.GetLength(i); } var target = Array.CreateInstance(elementType, lengths); context.RecordCopy(sourceAsArray, target); var index = new int[rank]; var sizes = new int[rank]; sizes[rank - 1] = 1; for (var k = rank - 2; k >= 0; k--) { sizes[k] = sizes[k + 1] * lengths[k + 1]; } for (var i = 0; i < sourceAsArray.Length; i++) { var k = i; for (var n = 0; n < rank; n++) { var offset = k / sizes[n]; k = k - offset * sizes[n]; index[n] = offset; } // using objects will cause a performance issue // for value types due to boxing/unboxing. // TODO: Find a way to deal with this in a strongly // typed fashion. object sourceItem = sourceAsArray.GetValue(index); if (sourceItem != null) { target.SetValue(Cloner <object> .Get(sourceItem, context), index); } } return((T)(object)target); }