internal static void Construct <TDstContainer, TSrcContainer>(
     ref TDstContainer dstContainer,
     ref TSrcContainer srcContainer,
     VisitResult result,
     PropertyContainerConstructOptions options = default)
 {
     if (RuntimeTypeInfoCache <TDstContainer> .IsAbstractOrInterface() || typeof(TDstContainer) != dstContainer.GetType())
     {
         var propertyBag = PropertyBagResolver.Resolve(dstContainer.GetType());
         var action      = new ConstructAbstractType <TSrcContainer>
         {
             Options           = options,
             Result            = result,
             SrcContainer      = srcContainer,
             DstContainerBoxed = dstContainer
         };
         propertyBag.Cast(ref action);
         dstContainer = (TDstContainer)action.DstContainerBoxed;
     }
     else
     {
         var visitor = new TypeConstructionVisitor <TDstContainer>(dstContainer, result, options);
         Visit(ref srcContainer, ref visitor);
         dstContainer = visitor.Target;
     }
 }
        public TypeConstructionVisitor(TDstContainer dstContainer, VisitResult result, PropertyContainerConstructOptions options)
        {
            m_Options        = options;
            Result           = result;
            m_DstContainer   = dstContainer;
            m_DstPropertyBag = PropertyBagResolver.Resolve <TDstContainer>();

            if (null == m_DstPropertyBag)
            {
                throw new ArgumentException($"No property bag exists for the given Type=[{typeof(TDstContainer)}]");
            }
        }
        public static VisitResult Construct <TDstContainer, TSrcContainer>(ref TDstContainer dstContainer, ref TSrcContainer srcContainer, PropertyContainerConstructOptions options = default)
        {
            if (!RuntimeTypeInfoCache <TSrcContainer> .IsValueType() && srcContainer == null)
            {
                throw new ArgumentNullException(nameof(srcContainer));
            }

            if (!RuntimeTypeInfoCache <TDstContainer> .IsValueType() && dstContainer == null)
            {
                if (typeof(UnityEngine.Object).IsAssignableFrom(typeof(TDstContainer)))
                {
                    throw new ArgumentNullException(nameof(dstContainer));
                }

                if (!TypeConstruction.TryConstruct(srcContainer.GetType(), out dstContainer))
                {
                    throw new ArgumentNullException(nameof(dstContainer));
                }
            }

            var result = VisitResult.GetPooled();

            Construct(ref dstContainer, ref srcContainer, result, options);
            return(result);
        }