138 lines · 6.6 KB · C#
RawDownload
//******************************************************************************************************//  FastObjectFactory.cs - Gbtc////  Copyright © 2010, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/eclipse-1.0.php////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  01/25/2010 - James R. Carroll//       Generated original version of source code.//  10/8/2012 - Danyelle Gilliam//        Modified Header////******************************************************************************************************    using System;using System.Collections.Concurrent;using System.Reflection;using System.Reflection.Emit; namespace GSF{    /// <summary>    /// Quickly creates new objects based on specified type.    /// </summary>    /// <typeparam name="T">Type of object to create quickly.</typeparam>    /// <remarks>    /// You can use the alternate <see cref="FastObjectFactory"/> implementation if you only have the <see cref="Type"/> of    /// an object available (such as when you are using reflection).    /// </remarks>    public static class FastObjectFactory<T> where T : class, new()    {        // Static object creation delegate specific to type T - one instance will be created per type by the compiler        private static Func<T> s_createObjectFunction;         static FastObjectFactory()        {            // This is markedly faster than using Activator.CreateInstance            Type type = typeof(T);            DynamicMethod dynMethod = new DynamicMethod("ctor$" + type.Name, type, null, type);            ILGenerator ilGen = dynMethod.GetILGenerator();            ilGen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));            ilGen.Emit(OpCodes.Ret);            s_createObjectFunction = (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));        }         /// <summary>        /// Gets delegate that quickly creates new instance of the specfied type.        /// </summary>        public static Func<T> CreateObjectFunction        {            get            {                return s_createObjectFunction;            }        }    }     /// <summary>    /// Quickly creates new objects based on specified type.    /// </summary>    /// <remarks>    /// <see cref="FastObjectFactory"/> should be used when you only have the <see cref="Type"/> of an object available (such as when you are    /// using reflection), otherwise you should use the generic <see cref="FastObjectFactory{T}"/>.    /// </remarks>    public static class FastObjectFactory    {        // We cache object creation functions by type so they are only created once        private static ConcurrentDictionary<Type, Delegate> s_createObjectFunctions = new ConcurrentDictionary<Type, Delegate>();         /// <summary>        /// Gets delegate that creates new instance of the <paramref name="type"/>.        /// </summary>        /// <param name="type">Type of object to create quickly.</param>        /// <returns>Delegate to use to quickly create new objects.</returns>        /// <exception cref="InvalidOperationException"><paramref name="type"/> does not support parameterless public constructor.</exception>        public static Func<object> GetCreateObjectFunction(Type type)        {            return GetCreateObjectFunction<object>(type);        }         /// <summary>        /// Gets delegate of specified return type that creates new instance of the <paramref name="type"/>.        /// </summary>        /// <param name="type">Type of object to create quickly.</param>        /// <typeparam name="T">Type of returned object function used to create objects quickly.</typeparam>        /// <returns>Delegate to use to quickly create new objects.</returns>        /// <exception cref="InvalidOperationException">        /// <paramref name="type"/> does not support parameterless public constructor -or-         /// <paramref name="type"/> is not a subclass or interface implementation of function type definition.        /// </exception>        /// <remarks>        /// This function will validate that <typeparamref name="T"/> is related to <paramref name="type"/>.        /// </remarks>        public static Func<T> GetCreateObjectFunction<T>(Type type)        {            // Since user can call this function with any type, we verify that it is related to the return type. If return type            // is a class, see if type derives from it, else if return type is an interface, see if type implements it.            if (!type.IsAbstract &&            (               (typeof(T).IsClass && type.IsSubclassOf(typeof(T))) ||               (typeof(T).IsInterface && (object)type.GetInterface(typeof(T).Name) != null))            )            {                return (Func<T>)s_createObjectFunctions.GetOrAdd(type, (objType) =>                {                    // Get parameterless constructor for this type                    ConstructorInfo typeCtor = objType.GetConstructor(Type.EmptyTypes);                     if ((object)typeCtor == null)                        throw new InvalidOperationException("Specified type parameter does not support parameterless public constructor");                     // This is markedly faster than using Activator.CreateInstance                    DynamicMethod dynMethod = new DynamicMethod("ctor_type$" + objType.Name, objType, null, objType);                    ILGenerator ilGen = dynMethod.GetILGenerator();                    ilGen.Emit(OpCodes.Newobj, typeCtor);                    ilGen.Emit(OpCodes.Ret);                    return (Func<T>)dynMethod.CreateDelegate(typeof(Func<T>));                });            }            else                throw new InvalidOperationException("Specified type parameter is not a subclass or interface implementation of function type definition");        }    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t