views:

1732

answers:

18

So I tried searching SO hoping someone had a good explanation of this, with no luck.

I asked another friend of mine a different question (which I've now forgotten) and his answer was simply "reflection" before he signed off.

I am still very new to the C# world, having been an amateur VB.net programmer (also JavaScript, ActionScript, and C), and am trying as hard as I can to grasp these advanced concepts.

There's lots of philosophical answers -- "application looking at itself" -- but they don't provide any practical hints on what is actually going on or how it is used within that context.

So, what is reflection, why is it important, and why/how do I use it?

+3  A: 

Say you have two alternate implementations of an interface. You want to allow the user to pick one or the other, via a simple text config file.

With reflection, you can simply read the name of the class whose implementation you want to use from the config file (as a string), and instantiate an instance of that class.

Chase Seibert
I understand. So, essentially, you are saying reflection is the ability to determine what a mystery component/interface/DLL can do during runtime? That makes sense.
Tom the Junglist
+1  A: 

There are many cases in which the application should not assume much about itself and should look at runtime to see what it actually is. This is where reflection comes into the show. For example, ASP.NET makes no assumption about the membership provider you use except that it inherits the appropriate class. It uses reflection to lookup the class at runtime and instantiate it. This gives out a great deal of extensibility due to decoupling and decreasing dependencies between classes.

This is, of course, only a single use case for reflection. There could be many other cases where it might be very useful.

Mehrdad Afshari
+3  A: 

Reflection lets you dig into an assembly and use it, no matter that you don't have it referenced later.

Consider a plug-ins system, in which the host doesn't know about the plug-ins it will hold; with Reflection (and the correct architecture), you can construct a simple solution achieving this.

Consider another scenario in which you must to call the method on an object given a string, Reflection gives you the approach to achieve this as well.

There are many other usages but i hope these two, open your apetite to this excellent feature of CLR

Jhonny D. Cano -Leftware-
+2  A: 

Reflection is using the code to examine the code itself. For example, instead of calling foo.DoBar() you could call:

foo.GetType().GetMethod("DoBar").Invoke(foo,null);

That seems like a round-about method of getting to the same destination, but it can also be used to do some black magic that might break the rules, like calling private methods on framework classes, for example. It can also be used to actually generate code and output new binaries, and a whole slew of things that are extremely useful to a small group of people.

For more information, check out the MSDN section on Reflection.

tylerl
+7  A: 

(my defintion) Reflection is the ability to write static code that that executes code at run-time, that is normally determined at compile time.

For instance, I could call a class method to draw by compiling in that command eg:

pen.DrawLine()

or With reflection, I can first see if my object has a method called "drawline" and if so, call it. (Note this isn't the actual C# Reflection syntax)

 if(pen.Methods.Contains("DrawLine"))
 {
    pen.InvokeMethod("DrawLine"))
 }

I'm no reflection master, but I used reflection for a plug-in architecture.

With reflection I can load a .NET assembly (a dll in this case) at run time, find out all the types that are in the .NET Assembly, see if any of those types implement a specific interface, and if so, instantiate the class, to which I invoke the interface methods.

I know that use-case is a bit technical, but essentially reflection allows me to load plug-ins dynamically (ie at run-time), and lets me make type-safe calls to it.

Alan
+1  A: 

Andrew Troelsen, author of Pro C# 2008 and the .NET 3.5 Platform, defines reflection this way:

In the .NET universe, reflection is the process of runtime type discovery.

I'm not sure I could give you an accurate explanation of what that means, but I can tell you how I've used it.

I can put a user-defined attribute on an assembly (dll). Using reflection at run-time, I can inspect all of the assemblies in a certain directory location to see if they have this attribute defined. This can clue my application on how to use the assembly, say as a plug-in.

I've also used reflection to load and save application settings.


For what it's worth, unless you're using reflection, I'm not sure what it has to do with your GUI throwing exceptions.

About the only thing I know about C# reflection is that it is annoying as hell because all my GUI apps like to throw incredibly annoying, pointless "Exception has been thrown by the target of an invocation" exceptions at Application.Run(new frmMain());, instead of stopping where the real problem happened (as shown in the innerException).

Your statement makes me believe you have few if any try/catch blocks anywhere in your application such that every exception is percolating back to the top of the call stack. If you are using Visual Studio 2005/2008 in debug mode, go into the Debug menu and select the Exceptions... menu option. Inside the Exceptions dialog, check the checkboxes under the Thrown column. Now, when you run your application and an exception is thrown, the debugger will break where the exception is thrown.

Matt Davis
At the moment, yeah, a lot of my exceptions are uncut and are percolating back to the top. I'm in the process of stabilizing things and this is making it difficult to pinpoint exactly what went wrong -- but the app has a ton of experimentation so try...catch wasn't always written in. Thanks!
Tom the Junglist
Well, not difficult... but annoying.
Tom the Junglist
A: 

Reflection is so named because it allows ones code to take a look at itself just like looking in a mirror.

As previously mentioned reflection may be used to create new instances using a class name. Serialization is also powered by reflection. In this case the code examines all the serializable fields and serializes those recursively until the entire graph has been consumed and its byte form written.

Reflection allows one to escape static typing at compile time by discovering types, methods, fields etc at runtime. Many dynamic languages on the JVM (not sure about CLR but id imagine the same is true) use reflection to dispatch methods.

mP
+3  A: 

It's sometimes useful to be able to read properties or invoke methods of a class without knowing what properties or methods a class has at design time. The way to accomplish this is with reflection. As demonstrated by the code below, you can get a list of all properties on a class and retrieve their values without knowing anything about it at compile time. Or you can get a method by name, even if you don't know the name of the method at compile time, and invoke it via reflection. This would allow you, for example, to create a scripting language that operates on objects defined in another user-supplied DLL. (Of course you can also enumerate all methods in a class or retrieve a specific property by name, but these cases are not demonstrated in the code below.)

class Program
{
  static void Main(string[] args)
  {
     UserDefinedClass udc = new UserDefinedClass();
     udc.UserProperty = "This is the property value";

     ClassTracer ct = new ClassTracer(udc);
     ct.TraceProperties();
     ct.CallMethod("UserFunction", "parameter 1 value");
  }
}

class ClassTracer
{
  object target;

  public ClassTracer(object target)
  {
     this.target = target;
  }

  public void TraceProperties()
  {
     // Get a list of all properties implemented by the class
     System.Reflection.PropertyInfo[] pis = target.GetType().GetProperties();
     foreach (System.Reflection.PropertyInfo pi in pis)
     {
        Console.WriteLine("{0}: {1}", pi.Name, pi.GetValue(target, null));
     }
  }

  public void CallMethod(string MethodName, string arg1)
  {
     System.Reflection.MethodInfo mi = target.GetType().GetMethod(MethodName);
     if (mi != null)
     {
        mi.Invoke(target, new object[] { arg1 });
     }
  }
}

class UserDefinedClass
{
  private string userPropertyValue;

  public string UserProperty
  {
     get
     {
        return userPropertyValue;
     }
     set
     {
        userPropertyValue = value;
     }
  }

  public void UserFunction(string parameter)
  {
     Console.WriteLine("{0} - {1}", userPropertyValue, parameter);
  }
}
BlueMonkMN
+5  A: 

The most common use of reflection is an extension of what used to be called RTTI (run-time type information) and was primarily the domain of C++ programmers.

Reflection is a side-effect of the way .net is built and that Microsoft elected to expose the libraries they used to create Visual Studio and the .net run-time to developers outside of Microsoft.

Most of the reflection library focuses on type discovery and creation that can be invoked at run-time. This allows for some very powerful self-referential code. Take the following example at the heart of our configuration management system (some bits deleted for clarity):

    public static IMyCompanySetting UnwrapSetting(XmlNode settingNode)
    {

        string typeName = settingNode.Attributes["type"].Value;
        string typeAssembly;
        if(settingNode.Attributes["assembly"] != null)
        {
            typeAssembly = settingNode.Attributes["assembly"].Value;
        }

        Type settingType = null;
        Assembly settingAssembly = null;
        try
        {
            // Create an object based on the type and assembly properties stored in the XML
            try
            {
                settingAssembly = Assembly.Load(typeAssembly);
                if (settingAssembly == null)
                {
                    return null;
                }
            }
            catch (Exception outerEx)
            {
                try
                {
                    settingType = GetOrphanType(typeName);
                }
                catch (Exception innerEx)
                {
                    throw new Exception("Failed to create object " + typeName + " :: " + innerEx.ToString(), outerEx);
                }
            }

            // We will try in order:
            // 1. Get the type from the named assembly.
            // 2. Get the type using its fully-qualified name.
            // 3. Do a deep search for the most basic name of the class.
            if (settingType == null && settingAssembly != null) settingType = settingAssembly.GetType(typeName);
            if (settingType == null) settingType = Type.GetType(typeName);
            if (settingType == null) settingType = GetOrphanType(typeName);
            if (settingType == null) throw new System.Exception(
                String.Format("Unable to load definition for type {0} using loosest possible binding.", typeName));
        }
        catch (Exception ex)
        {
            throw new CometConfigurationException(
                String.Format("Could not create object of type {0} from assembly {1}", typeName, typeAssembly), ex);
        }

        bool settingIsCreated = false;
        IMyCompanySetting theSetting = null;

        // If the class has a constructor that accepts a single parameter that is an XML node,
        // call that constructor.
        foreach (ConstructorInfo ctor in settingType.GetConstructors())
        {
            ParameterInfo[] parameters = ctor.GetParameters();
            if (parameters.Length == 1)
            {
                if (parameters[0].ParameterType == typeof(XmlNode))
                {
                    object[] theParams = { settingNode };
                    try
                    {
                        theSetting = (IMyCompanySetting)ctor.Invoke(theParams);
                        settingIsCreated = true;
                    }
                    catch (System.Exception ex)
                    {
                        // If there is a pre-existing constructor that accepts an XML node
                        // with a different schema from the one provided here, it will fail
                        // and we'll go to the default constructor.
                        UtilitiesAndConstants.ReportExceptionToCommonLog(ex);
                        settingIsCreated = false;
                    }
                }
            }
        }

This code allows us to create a limitless number of classes that implement IMyCompanySetting and serialize and deserialize themselves using XML. Then, given a chunk of XML that is the output of object serialization, the system can turn it back into an object, even if the object itself is from a library that the serialization library doesn't have staticly linked.

There are 3 things that reflect does here that would be impossible without it:

Load an assembly at run-time based on its name.

Load an object from an assembly at run-time, based on its name.

Call an object constructor based on signature for an object of a class that is not known at compile time.

Jekke
+1  A: 

I have used reflection to implement a custom data bindings system.

For example, with my bindings API I can write the following:

Binding b = new Binding(textBox, "Text", myObject, "Text", BindingMode.Bidirectional);

Any changes to the text in the textBox object are detected by the Binding object (which attaches to the TextChanged event) and passed into the myObject.Text property. Changes to myObject.Text are detected (by its TextChanged event) and passed into the textBox.Text member.

I implemented this system using reflection. The Binding constructor is declared as:

Binding(object, string, object, string, BindingMode)

The system therefore works with any object (with one important proviso).

I inspect the first object and find the member corresponding to the named member in the first string (textBox and "Text", ie. does textBox have a member called "Text"). Repeat with the second object and string.

Proviso: for objects to be used in this scheme they must implement the informal requirement that any bindable property must have a corresponding PropertyNameChanged event. Happily, pretty much all the .Net UI components follow this convention.

I then inspect the object for the requisite PropertyNameChanged events, add event handlers to them, and everything is set.

NB. I implemented this in .Net 1.0, so it predates Microsoft's bindings implementation - which I have not yet got round to investigating.

Rob
+1  A: 

Let's say you have some business entities which all come derive from a base class called Entity. Let's also say that you need/want all the derived classes to be cloneable. You can implement a method "Clone" (interface ICloneable) on the base class which would loop through all the properties of the current class (although it is implemented at the Entity class) and copy them to the cloned object. This is a case where Reflection can really help. Because you can't know the name and the count of the properties at the base class. And you don't want to implement the method in all derived classes. However you might want to make the method virtual.

Andrei Rinea
+7  A: 

Reflection provides the ability to determine things and execute code at runtime.

You don't have to use it if you don't want to, but it is extremely handy for dynamic behavior.

For example:

a) You can use reflection to configure your application by loading an external configuration file and starting services based on it. Your application wont have to know in advance about the classes that implement those services, as long as they conform to a specific interface or API.

b) Using reflection you can generate classes and code on the fly, which simplifies certain programming tasks since the programmer does not have to explicitly create all the needed code.

c) Reflection is also invaluable for programs that work by examining code. An example of that would be an IDE or a UI designer.

d) Reflection helps you reduce boilerplate code.

e) Reflection is handy for defining mini Domain Specific Languages (DSL) in your code.

foljs
+1  A: 

Other people have answered for

what is reflection, why is it important

So I will be answering following questions only.

How do I use it?

Through following namespaces

Why do I use it?

To invoke/inspect assembly types, members, properties

When you look at a product like Reflector, being able to inspect code structure is more than practical enough.

Sung Meister
+1  A: 

Practical Application

Use reflection for aligning Data with objects, as in a data mapping situation. For example, you can map a database column to an object's property. If you were to write an Object Relational Mapper, you would need some way to get from a configuration setting (i.e. DatabaseColumnName maps to Class.MemberName) to the objects to which it referring.

Greg Ogle
+1  A: 

If you run fast and furious, maybe you're inheriting from an object and need access to a private field. You don't have source, but thats ok you have Reflection. (hacky I know)

A more legitimate use I've seen is to use reflection in implementing C# generics where I want to do some operation on the generic type that isn't otherwise available. The only operations available on a generic type are those made available with a generic constraint (ie, if you constrain the generic type to implement IFoo, you can use IFoo methods on instances of that class). Some operations though just aren't available- for instance I was taking a generic class that was supposed to have a particular non-default constructor. I couldn't constrain the generic method to only accept generic type parameters with that constructor, but at least I could try and use that constructor when implementing the generic via reflection.

I use reflection sparingly but it occasionally comes in real handy.

Frank Schwieterman
A: 

In terms of a practical use for reflection we have used it to allow our customers to provide their own localisation.

With our applications we provide a local resource database that the client can work through providing language translation for all strings, menu items, dialog controls...etc. With this client translated database in place we then use reflection on application launch and iterate through all our controls and replace default language strings with the client supplied translated strings.

Lou
A: 

There are many uses for reflection that have already been detailed here but another use might be to log the state of an object including its private members for use in debugging.

b_richardson
A: 

Can you post some sample code which shows how you are performing reflection? Do you have the PDB files in the same location as the assembly on which you are using the reflection API's? If so, then in Visual studio go to the Debug menu -->Exceptions and check the check box "Common Language runtime thrown". Run your application in debug mode. Hopefully the debugger should break at the point in your reflected assembly at which the real exception is being thrown.

Abhijeet Patel