Click here to Skip to main content
15,896,154 members
Articles / Programming Languages / MSIL

Fasterflect - a fast and simple API for Reflection invocation

Rate me:
Please Sign up or sign in to vote.
4.82/5 (14 votes)
9 Aug 2009Apache8 min read 70.6K   937   50  
Examine the implementation, API, and performance for Fasterflect, an alternative to the .NET Reflection API.
#region License
// Copyright 2009 Buu Nguyen (http://www.buunguyen.net/blog)
// 
// Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License.
// 
// The latest version of this file can be found at http://fasterflect.codeplex.com/
#endregion

using System;
using System.Collections.Generic;
using System.Threading;

namespace Fasterflect.Emitter
{
    internal class DelegateCache
    {
        private readonly Dictionary<CallInfo, Delegate> map = new Dictionary<CallInfo, Delegate>();
        private readonly ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();

        /// <summary>
        /// Get the corresponding delegate for the specified <param name="callInfo"/>.
        /// If there's no existing delegate, a new one is created by invoking the 
        /// construction method <param name="func" /> and the result is added to the map
        /// for subsequent accesses.
        /// 
        /// This method assures that one and only one delegate can be created for 
        /// any particular instance of <param name="callInfo"/>.
        /// </summary>
        public Delegate GetDelegate(CallInfo callInfo, Func<Delegate> func)
        {
            Delegate action;
            bool exist;
            rwLock.EnterReadLock();
            try 
            {
                exist = map.TryGetValue(callInfo, out action);
            }
            finally
            {
                rwLock.ExitReadLock();
            }
            
            if (exist) return action;

            rwLock.EnterWriteLock();
            try
            {
                if (!map.ContainsKey(callInfo))
                {
                    action = func();
                    map.Add(callInfo, action);
                }
            } 
            finally
            {
                rwLock.ExitWriteLock();
            }
            return action;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Chief Technology Officer KMS Technology
Vietnam Vietnam
You can visit Buu's blog at http://www.buunguyen.net/blog to read about his thoughts on software development.

Comments and Discussions