Пример #1
0
        /// <summary>
        /// Constructs a new instance of <see cref="LazyInitObject{T}"/>.
        /// </summary>
        ///
        /// <param name="initFunc">A delegate that must be called during initialization to obtain the
        /// object's value.</param>
        /// <param name="initLock">An object that will be used as a lock to ensure thread safe
        /// initialization. If this is null, a lock object is created internally and used.</param>
        /// <param name="recursionHandling">Specifies how accesses to the object within the
        /// initialization function are handled.</param>
        public LazyInitObject(
            Func <T> initFunc,
            object?initLock = null,
            LazyInitRecursionHandling recursionHandling = LazyInitRecursionHandling.THROW
            )
        {
            if (initFunc == null)
            {
                throw new ArgumentNullException(nameof(initFunc));
            }

            if (recursionHandling > LazyInitRecursionHandling.RECURSIVE_CALL)
            {
                throw new ArgumentOutOfRangeException(nameof(recursionHandling));
            }

            if (initLock == null)
            {
                initLock = new object();
            }

            m_value            = default(T);
            m_initFunc         = initFunc;
            m_initLock         = initLock;
            m_recursionHandler = recursionHandling;
            m_state            = LazyInitObjectState.UNINITIALIZED;
        }
Пример #2
0
        private T _internalGetValue()
        {
            if (m_initLock == null)
            {
                throw new InvalidOperationException("Cannot access the value of a default-initialized LazyInitObject.");
            }

            lock (m_initLock) {
                LazyInitObjectState state = m_state;
                if (state == LazyInitObjectState.COMPLETE)
                {
                    return(m_value !);
                }

                if (state == LazyInitObjectState.FAILED)
                {
                    throw new InvalidOperationException("Cannot access lazy object after initialization failure.");
                }

                if (state == LazyInitObjectState.IN_INITIALIZER)
                {
                    if (m_recursionHandler == LazyInitRecursionHandling.THROW)
                    {
                        throw new InvalidOperationException("Cannot access lazy object in initializer.");
                    }

                    if (m_recursionHandler == LazyInitRecursionHandling.RETURN_DEFAULT)
                    {
                        return(default(T) !);
                    }
                }

                m_state = LazyInitObjectState.IN_INITIALIZER;
                T value;
                try {
                    value = m_initFunc();
                }
                catch {
                    m_state    = LazyInitObjectState.FAILED;
                    m_initFunc = null !;    // This will never be called again
                    throw;
                }

                m_value    = value;
                m_state    = LazyInitObjectState.COMPLETE;
                m_initFunc = null !;    // This will never be called again

                return(value);
            }
        }