Click here to Skip to main content
15,895,370 members
Articles / Programming Languages / C#

Improving Code Auto Completion in C#

Rate me:
Please Sign up or sign in to vote.
4.89/5 (31 votes)
16 Sep 2009CPOL7 min read 65.8K   1.3K   92  
An article on improving code completion in C#.
//-------------------------------------------------------------------------------------
// <copyright file="ReflectionHelper.cs" company="Jonno">
//     Copyright (c) 2009 Paul Johnson (paulmichael.johnson@gmail.com) 
//     Code is released under The Code Project Open License (CPOL).       
// </copyright>
//-------------------------------------------------------------------------------------

namespace Jonno.Reflection
{
    using System;
    using System.Reflection;
    using Jonno.Extensions;

    /// <summary>
    /// Runs methods in a class using reflection. 
    /// Can be used to run Private methods, or check private properties for testing purposes.
    /// </summary>
    /// <typeparam name="T">The type to work on.</typeparam>
    /// <typeparam name="TResult">The type of any expected result.</typeparam>
    public static class ReflectionHelper<T, TResult>
    {
        /// <summary>
        /// The flags that control the reflection binding for instances.
        /// </summary>
        private const BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

        /// <summary>
        /// The flags that control the reflection binding for statics.
        /// </summary>
        private const BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

        /// <summary>
        /// Gets a property value from an instance object using Reflection.
        /// </summary>        
        /// <param name="property">The name of the property.</param>
        /// <param name="instance">The instance object.</param>
        /// <returns>The value of the property.</returns>        
        public static TResult GetInstanceProperty(string property, object instance)
        {
            return GetProperty(property, instance, InstanceFlags);
        }

        /// <summary>
        /// Gets a static property value from a class using Reflection.
        /// </summary>        
        /// <param name="property">The name of the property.</param>        
        /// <returns>The value of the property.</returns>        
        public static TResult GetStaticProperty(string property)
        {
            return GetProperty(property, null, StaticFlags);
        }

        /// <summary>
        /// Gets a property value from an instance object using Reflection.
        /// </summary>        
        /// <param name="property">The name of the property.</param>
        /// <param name="instance">The instance object.</param>
        /// <returns>The value of the property.</returns>
        /// <param name="flags">The binding flags to use.</param>
        public static TResult GetProperty(string property, object instance, BindingFlags flags)
        {
            var t = typeof(T);

            var info = t.GetProperty(property, flags);

            if (info == null || !info.CanRead)
            {
                ThrowArgumentException(property, t);
            }

            return (TResult)info.GetValue(instance, null);            
        }

        /// <summary>
        /// Gets a field value from an instance object using Reflection.
        /// </summary>        
        /// <param name="member">The name of the field.</param>
        /// <param name="instance">The instance object.</param>
        /// <returns>The value of the field.</returns>        
        public static TResult GetInstanceField(string member, object instance)
        {
            return GetField(member, instance, InstanceFlags);
        }

        /// <summary>
        /// Gets a static field value from a class using Reflection.
        /// </summary>        
        /// <param name="member">The name of the field.</param>        
        /// <returns>The value of the field.</returns>        
        public static TResult GetStaticField(string member)
        {
            return GetField(member, null, StaticFlags);
        }

        /// <summary>
        /// Gets a field value from an instance object using Reflection.
        /// </summary>        
        /// <param name="member">The name of the field.</param>
        /// <param name="instance">The instance object.</param>
        /// <returns>The value of the field.</returns>
        /// <param name="flags">The binding flags to use.</param>
        public static TResult GetField(string member, object instance, BindingFlags flags)
        {
            var t = typeof(T);

            var m = t.GetMember(member, flags);
            FieldInfo f = null;

            try
            {
                f = (FieldInfo)m[0];                
            }
            catch
            {
                ThrowArgumentException(member, t);
            }

            return (TResult)f.GetValue(instance);     
        }
      
        /// <summary>
        /// Runs a method by using Reflection.
        /// </summary>        
        /// <param name="method">The name of the method to call./</param>
        /// <param name="instance">The instance object that will call the method.</param>        
        /// <param name="args">The methods arguments.</param>
        /// <returns>The object that is returned by the method.</returns>
        public static TResult RunInstanceMethod(string method, object instance, ref object[] args)
        {
            return RunMethod(method, instance, InstanceFlags, ref args);
        }

        /// <summary>
        /// Runs a method by using Reflection.
        /// </summary>        
        /// <param name="method">The name of the method to call./</param>        
        /// <param name="args">The methods arguments.</param>
        /// <returns>The object that is returned by the method.</returns>
        public static TResult RunStaticMethod(string method, ref object[] args)
        {
            return RunMethod(method, null, StaticFlags, ref args);
        }
                
        /// <summary>
        /// Runs a method by using Reflection.
        /// </summary>        
        /// <param name="method">The name of the method to call./</param>
        /// <param name="instance">The instance object that will call the method.</param>
        /// <param name="flags">The binding flags to use.</param>
        /// <param name="args">The methods arguments.</param>
        /// <returns>The object that is returned by the method.</returns>
        public static TResult RunMethod(string method, object instance, BindingFlags flags, ref object[] args)
        {
            var t = typeof(T);
     
            try
            {
                var m = t.GetMethod(method, flags);

                if (m == null)
                {
                    ThrowArgumentException(method, t);                    
                }

                return (TResult)m.Invoke(instance, args);
            }
            catch (TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    throw ex.InnerException;
                }
                else
                {
                    throw ex;
                }
            }
            catch
            {
                throw;
            }
        }

        private static void ThrowArgumentException(string value, Type t)
        {
            throw new ArgumentException(string.Format("There is no '{0}' for type '{1}", value, t.ToString()));
        }    
    }
}

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 Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I have over 15 years of development experience, in many different languages, programming styles and platforms. Currently working as a C# coder, and residing in north Herts in the UK. I love lean software development and anything that reduces a grind to leave more time for useful coding!

Comments and Discussions