/// <summary> /// Tries to cast arrays elements of type <typeparamref name="T"/> to array result, containing elements of type <typeparamref name="TTo"/>. /// If casting fails for any member, will return false and set result to null. /// </summary> /// <typeparam name="TTo"> /// Cast to an array with members of this type. </typeparam> /// <param name="sourceArray"> /// Array whose contents will be cast to target type.</param> /// <param name="disposeSourceArray"> /// True if we are allowed to pool the source array after the casting has been completed. Note that this does not guarantee that the array will get disposed.</param> /// <param name="result"> /// An array of type TTo[]. If target and source types are the same, simply equals sourceArray. Length of array will be equal or less than that of sourceArray, depending /// on whether or not all members can be cast. /// </param> /// <returns> /// True if casting succeeds for all array elements, otherwise returns false. /// </returns> public static bool TryCast <TTo>(T[] sourceArray, bool disposeSourceArray, out TTo[] result) where TTo : T { var fromType = sourceArray.GetType(); var toType = typeof(TTo[]); if (disposeSourceArray) { if (fromType.Equals(toType)) { #if DEV_MODE Debug.LogWarning("No need to cast from " + fromType.Name + " to " + toType.Name + " because they are the same"); #endif result = sourceArray as TTo[]; return(true); } } int count = sourceArray.Length; result = ArrayPool <TTo> .CreateInternal(count, false); try { for (int n = count - 1; n >= 0; n--) { result[n] = (TTo)sourceArray[n]; } } catch (InvalidCastException) { result = null; return(false); } if (disposeSourceArray) { Dispose(ref sourceArray); } return(true); }
/// <summary> /// Casts array with elements of type <typeparamref name="T"/> to array of elements of type <typeparamref name="TTo"/> /// </summary> /// <typeparam name="TTo"> /// Cast to an array with members of this type </typeparam> /// <param name="sourceArray"> /// Array whose contents will be cast to target type. </param> /// <param name="disposeSourceArray"> /// True if we are allowed to pool the source array after the casting has been completed. Note that this does not guarantee that the array will get disposed.</param> /// <returns> /// An array of type TTo[]. If target and source types are the same, simply returns sourceArray. /// </returns> public static TToStruct[] CastToValueTypeArray <TToStruct>(T[] sourceArray, bool disposeSourceArray = false) where TToStruct : struct { var fromType = sourceArray.GetType(); var toType = typeof(TToStruct[]); if (disposeSourceArray) { if (fromType == toType) { #if DEV_MODE Debug.LogWarning("No need to cast from " + fromType.Name + " to " + toType.Name + " because they are the same"); #endif return(sourceArray as TToStruct[]); } } int count = sourceArray.Length; var result = ArrayPool <TToStruct> .CreateInternal(count, false); for (int n = count - 1; n >= 0; n--) { result[n] = (TToStruct)(object)sourceArray[n]; } if (disposeSourceArray) { Dispose(ref sourceArray); #if DEV_MODE && PI_ASSERTATIONS var inspectors = InspectorUtility.ActiveManager.ActiveInstances; for (int n = inspectors.Count - 1; n >= 0; n--) { Debug.Assert(!inspectors[n].State.inspected.ContainsNullObjects()); } #endif } return(result); }
/// <summary> /// Casts array with elements of type <typeparamref name="T"/> to array of elements of type <typeparamref name="TTo"/>. /// Will skip elements that cannot be cast to target type. /// </summary> /// <typeparam name="TTo"> /// Cast to an array with members of this type. </typeparam> /// <param name="sourceArray"> /// Array whose contents will be cast to target type. </param> /// <param name="disposeSourceArray"> /// True if we are allowed to pool the source array after the casting has been completed. Note that this does not guarantee that the array will get disposed.</param> /// <returns> /// An array of type TTo[]. If target and source types are the same, simply returns sourceArray. Length of array will be equal or less than that of sourceArray, depending /// on whether or not all members can be cast. /// </returns> public static TTo[] CastWhereCastable <TTo>(T[] sourceArray, bool disposeSourceArray) where TTo : class, T { var fromType = sourceArray.GetType(); var toType = typeof(TTo[]); if (disposeSourceArray) { if (fromType.Equals(toType)) { #if DEV_MODE Debug.LogWarning("No need to cast from " + fromType.Name + " to " + toType.Name + " because they are the same"); #endif return(sourceArray as TTo[]); } } int count = sourceArray.Length; var result = ArrayPool <TTo> .CreateInternal(count, false); for (int n = count - 1; n >= 0; n--) { try { result[n] = (TTo)sourceArray[n]; } catch (InvalidCastException) { result = result.RemoveAt(n); } } if (disposeSourceArray) { Dispose(ref sourceArray); } return(result); }