I was wondering myself if is that possible I download the C# class source text from a webserver and use Activator to unwrap and use this code.
Is that possible to do ?
No but yes. You can't add inline source code in C# if it hasn't been compiled. You can use scripting languages to do this like Python or F#. You can however parse the code out and use reflection to create a dynamic assembly and run the code but you're technically writing a mini compiler inside of your source code to do this and it would be a MASSIVE undertaking.
Related
I have a C# source code in the file (or in text string). How can I use reflection emit to generate and execute this code?
There are so many examples where people generate one class, then add a method etc, but I need top compile-on-the-fly huge piece of C# code, couple kilobytes.
Reflection.Emit is for working with code at the IL level, it knows nothing about how to compile C# source code, so you can't use it for that.
What you can use for this instead is CodeDOM, specifically the CSharpCodeProvider class and its CompileAssemblyFromFile () or CompileAssemblyFromSource() methods.
I am reading the book "CLR Via C#" and in the Generics chapter is said:
Source code protecton
The developer using a generic algorithm doesn't need to have access to the algorithm's source code. With C++ templates or Java's generics, however, the algorithm's source code must be available to the developer who is using the algorithm.
Can anyone explain what exactly is meant by this?
Well, Generic classes are distributed in compiled form, unlike C++, where templates need to be distributed in full source code. So you do not need to distribute the C# source code of a library that contains generic classes.
This does not prevent the Receiver of your class from disassembling it though (as it is compiled to IL which can be rather easily decompiled again). To really protect the code, additional methods, such as obfuscation are required.
Behind the scene: This distribution in compiled form is the reason why C# generics and C++ templates also differ in the way they need to be written. C# generic classes and their methods need to be fully defined at the time of compilation, and any error in the definition of the generic class or their methods or any operation on a template parameter which cannot be deduced at compile time will directly produce a compile error. In C++ the template is only compiled at the time of usage and only the methods actually used are compiled. If you have an undefined operation or even a syntactical error in a template definition, you will only see the error when that function is actually instantiated and used.
I have stored some C# code in a database table.
I have the whole code of a base class in a string.
With the stored C# code in hand, I add to the class a method named m1 that contains a return <<some C# code>>; (the method always returns object so the C# code can be: 88 + 90, "hello world", this.ToString(), etc.), save it to a file and compile it with CSharpCodeProvider, and run it on my program.
The stored C# code can use some methods in the base class.
This scheme works very well.
Now, I would to use Reflection.Emit to do this, to avoid the compiling step.
Is this possible, and if so, how would it be done?
Now, I would to use Reflection.Emit to do this, to avoid the compiling step.
That doesn't make much sense to me. If you have source code that you want to execute, you basically have two options:
Compile it to some other form that can then be directly executed. (Classic compiled languages like C work like this.)
Parse it into some in-memory structure and then execute that, piece by piece. (Classic interpreted languages work like this, like JavaScript in older browsers.)
Things aren't actually as simple as that these days, because of virtual machines and intermediate languages etc., but those are the basic choices.
If you don't want to use CodeDOM, that leaves you two choices (corresponding to the two options above):
Parse the code and then create some executable form from it, possibly using Reflection.Emit.
Parse the code and directly execute the result. You don't need Reflection.Emit for that.
Choice 1 means you would need to implement full C# compiler. Choice 2 means you would need to implement a half of C# compiler, plus an interpreter of your in-memory structure. In both cases, it would be a giant project and you wouldn't really “avoid the compiling step”.
In Java we have used the javaagent argument and ASM (http://asm.ow2.org/) utilities to modify the byte code at run/load time in memory by the classloader . (aka Add a method call to a method in a class dynamically).
Once example of this is where you remove all calls to Log4j to speed up an application (http://surguy.net/articles/removing-log-messages.xml).
I’m trying to figure out how to do this same process on runtime with C# / .Net. I have seen that you can manipulate the CIL for .Net, but I haven’t found an example of this at runtime.
System.Reflection.Emit seems to be the closest .Net equitant where you can dynamically create classes, but is there a way to add to or override existing classes using this?
I have never used Mono.Cecil for generating dynamic code (it does make your life much easy if you want to instrument assemblies though).
In .Net if you want to generate code you can use System.CodeDom and System.Reflection.Emit. One particular useful class that enables you to inject methods dynamically is DynamicMethod.
Check out the newer features in .net 4, I think most of what your looking for is in the System.Dynamic namespace.
Check out this post on DuckTyping
It's been a while since I looked at it (I'm pretty much a Java bunny) but I think the Mono project had something called Cecil which did at least some of this.
How to get the classes that are available in a '.cs' file.? Like we can get the classes and methods in an Assembly using,
Assembly.GetTypes() and Type.GetMethods()
to get the Class and methods in an Assembly.
Similarly how to get all the classes present within a C# file(.cs file).? I need to get the classes in a .cs file from which i can easily get the methods within them and further details like parameters of methods etc.
Short of using a C# parser, there's no direct way of doing it. You could compile the .cs file using CSharpCodeProvider (which only works if the file compiles on its own and you can tell all the referenced assemblies to the compiler) and use reflection on the resulting assembly.
I recommend you to use a parser generator tool to generate a quick c# parser, you can use Antlr.
Also you can check this and this
The compiler erases all notions of a codefile from your code as it is compiled. That being said perhaps it is possible to retrieve the information you want from debugging symbols if they are available in your assembly.
From with in the class you can always call
this.GetType()
or outside the class you can always call
obj.GetType()
however when you compile an application, which is required for reflection to work, you can no longer get their definitions by file.
I've done this previously by invoking the C# compiler, compiling the C# file and then using reflection on the outputted type. This is possible if the C# file is a standalone file and doesn't have any dependencies.
However, the correct way would be to use a parser - something which isn't that easy to do. There are a couple of options available, MinosseCC being one of them.
Incidentally, C# 5.0 will make it a lot easier to compile code on the fly by being able to compile a String and getting back executable code. Can't wait for this - it's sure to confuse everyone that reads my code.
First of all, there is no such thing as the .cs file in which a class is defined. A class can be marked as partial and parts can be defined in several .cs files.
When you compile with debug information, the filenames for each method remain in the assembly (for each line of the source file, the corresponding IL commands are tagged).
Unfortunately, I don't know an easy way to get to that information from within the running application (without parsing the assembly file manually).
If you are safe calling the method, you can call it and in parallel construct a stack trace (from another thread) - in the StackFrame object you will find the original file name. But this is slow (as you have to call every method just to find that the filename is different) and risky (what if the method formats your hard drive?).
So, the only way you could go is try to parse the .cs file with a parser like AntLR yourself.