I am working on a program that generates a C# class (with constructors and properties) by giving its members and their types. My problem is how can I find out what using directive to write at the beginning of the file so that the class file will compile even if , for example, the user gives as an input an Arraylist member.
If I ask for a Timer, how could you possibly know whether I want
- a Windows.Forms.Timer
- a Threading.Timer
- a Timers.Timer
all of these are standard classes in .NET
Apart from that, you could either search all the system dll's using reflection
(that will take way too much time), or include a little Dictionary that you
populate by programmatically adding those entries that you consider important,
and interact with the user about everything else.
Thank you for your answer. I guess the dictionary solution is the only one I have to address this issue. In case a user wants to add a type of class that is not contained in my collection I will let him/her to add the appropiate namespace to the dictionary .Is there a faster way than reflection to find out if the namespace is correct?
Is there a faster way than reflection to find out if the namespace is correct?
Not as far as I know. And it would be expensive: you would have to create
a separate AppDomain I guess, then try to list all DLL candidates, load them
(either all at once, exhausting memory, or one at the time; removing it is
only possible by unloading the AppDomain).
Warning: even the Dictionary approach is just an approximation; if there
were only one Timer (say Timers.Timer) and you added it to the dictionary,
now the next .NET release adds a second Timer (say Threading.Timer), your dictionary
would not know it, and enforce one kind of Timer, whereas the user might want
So my guess is:
1) you should not even try to do the massive reflection at run-time (you might
do it once to generate a dictionary)
2) I would generate a very small dictionary manually; it suffices to recognize
a couple of the most popular classes for each DLL (e.g. File, FileStream,
FileInfo, Directory is all I would recognize to include System.IO), there is
no need to have an exhaustive list
3) whatever you do, it will only be an attempt, good enough to provide
an initial source file, not good enough for generating a ready-made and
error-free source file.
BTW: Actually, when I said Dictionary, that is not strictly correct, since
classnames are not unique (Timer example again).
I have an idea. I don't know if it is a good one but here it goes...
What if I try to instantiate an object of that type inside a using directive (using the namespace provided), catch the exception if it appears and notify the user...or by using System.Type.GetType() in some way...
There are only two ways to instantiate a class:
- the normal way, with the new keyword; it implies you have compiled correct code
hence you already have the necessary using statement (and the reference in your
- the reflective way, which means you load some assembly, locate the class,
and invoke its constructor; hence you must know which assembly to load; if you do,
you also know which using is required !
So the only thing that you can do is collect the source lines, add using statements
as much as you see fit, then try to compile and present (a summary of) the error
messages to the user.
I need using directives because I want to give my newly created class that is included in a given project a chance that it will compile. I don't want to let the user crash a good project with some typos or something. I think I will go with the suggestion of forcing the user to select a given type. Probably I will implement somekind of intellisense.
PIEBALDconsult I don't think you understant what am I doing. I am generating a C# code file (*.cs) row by row. Of course I need using directives when I start writing like, for example
"using System;". I don't intend to write using directives in any of the methods code.