Prev: Lauch .RDP from a C# App while keeping taskbar hidden
Next: Help with HttpFileCollection and keeping files in memory
From: Tony Johansson on 16 May 2010 06:13 Hi! I have hard to see a situation when I would use the reflection feature to create the code dynamically ? Can somebody give me a hint when this situation would arise ? It's much much easier to create the code in the normal way. //Tony
From: Alberto Poblacion on 16 May 2010 06:45 "Tony Johansson" <johansson.andersson(a)telia.com> wrote in message news:OZ4CzBO9KHA.4768(a)TK2MSFTNGP04.phx.gbl... > I have hard to see a situation when I would use the reflection feature to > create the code dynamically ? > Can somebody give me a hint when this situation would arise ? > It's much much easier to create the code in the normal way. Okay, I'll give you an example. Imagine the following challenge: You have to write a program where the user types-in a function such as "y=2*Cos(x)-1", and you have to paint an x-y graph showing that curve. Note that the expression is entered by the user into a textbox. You do not know it at compile time, so you cannot "create the code in the normal way", to quote your own words. To paint the graph, you would assign multiple values to x, and perform the operations to get the valye of y. You would then plot the (x,y) points into your output graphic. So, you need to produce code that is able to evaluate quickly, hundreds of times, a function that is entered by the user. How do you accomplish this? The first way that comes to mind is to use the CSharpComiler class to compile the expression, producing an assembly, and then invoke the method inside the assembly by means of reflection. This works, but the compilation process is not very fast (it uses a temporary file on disk) and it has the drawback that the assembly remains loaded in memory after you are done using it, so your program wil "leak" memory if you repeat the proccess many times as the user types new expressions. Of course, you could load the assembly into a different AppDomain and then unload it, but this would introduce additional complexity, and you would need to use cross-domain calls to evaluate the function. So, what is another alternative? Write a syntax analyzer to analyze the expression that the user typed, and then use Emit to produce some MSIL code that is equivalent to the expression. You then execute this code. The code is produced in memory (no temporary file), and the result is a DynamicMethod that evaluates the function as needed. The DynamicMethod is subject to garbage colection, so you will not leak memory if the process is repeated multiple times. If you want an example, you can take a look at an article the I wrote on this subject. The text of the article is written in Spanish, but you can copy and paste the C# code and it will work fine regardless of your language :-). This is the URL: http://www.scribd.com/doc/24018633/Como-crear-un-compilador-de-expresiones-en-NET
From: Arne Vajhøj on 16 May 2010 16:28 On 16-05-2010 06:13, Tony Johansson wrote: > I have hard to see a situation when I would use the reflection feature to > create the code dynamically ? > Can somebody give me a hint when this situation would arise ? > It's much much easier to create the code in the normal way. Yes. But that is only possible if the code is known at compile time. If you allow users to enter text at runtime and want to generate code based on that, then you need to dynamically generate code. Arne
From: Jehu Galeahsa on 16 May 2010 19:31
On May 16, 4:13 am, "Tony Johansson" <johansson.anders...(a)telia.com> wrote: > Hi! > > I have hard to see a situation when I would use the reflection feature to > create the code dynamically ? > Can somebody give me a hint when this situation would arise ? > It's much much easier to create the code in the normal way. > > //Tony Dynamically generated code is used for things like mock frameworks, for example. Recently, I created my own mock framework called Mockina. http://mockina.codeplex.com. Also, I have used it in the past to create lightweight decorator classes, such that they implement an interface simply by redirecting all calls to an underlying instance. The benefit here is that the decorator can track things like the number of times a method is called, how many references to the object are in memory and maintaining referential integrity. In the past, I wrote a really awesome tool that could read an Oracle database schema and generated an assembly of Data Transfer Objects matching the schema. Dynamically generated code also gives a very fine-grained control over code generation, even beyond what C# can allow syntactically. For instance, did you know that the accessors "protected internal" means, "Visible to subclasses OR classes in the same assembly." Some times you want "Visible to subclasses IN the same assembly." You can't achieve that with pure C# syntax. A lot of folks use the CodeDom namespace to generate text files with source code in them. Another option is to dynamically generate code and then use a decompiler to generate the files. The CodeDom namespace is actually limited in functionality; for instance, bitwise operations and using statements are not available. The best decompiler on the market can automatically convert try/finally/dispose patterns into using blocks. Generated code is also used in proxies, such as Web Services and .NET Remoting. In fact, under the hood of most of the major development tool enhancements in the past 5 years, reflection and dynamic code generation are performing a large majority of the work. Pure coding is great and all, but dynamic code generation is at the core of the modern development practice. It is a wonder why it is not taught more in schools. I would say that there is a great deal of benefit in teaching assembler in MSIL or ByteCode at this point, as well as at the machine level. |