Related
I am interested in writing a generic Intellisense enabled editor for SQL and C# (et al. if possible!). I would like to do this in C# as an overridden or extended WPF richTextBox-type control. I know there are many example projects available and I have implemented a basic version of my own; but most of the examples that I have come across (and indeed my own) are just that, basic.
A couple of code examples are:
DIY Intellisense By yetanotherchris
CodeTextBox - another RichTextBox control with syntax highlighting and Intellisense By Tamas Honfi
I have however, found a great example of an SQL editor with Intellisense QueryCommander SQL Editor By Mikael Håkansson which seems to work well. Microsoft must use a XML library of command keywords, but my question is: How (in detail) do Microsoft implement their Intellisense (as-you-type Intellisense) and how hard would it be for me to create my own of the same standard?
Edit A: A year on and I have managed to develop my own editor control with basic intellisense mainly for my own "enjoyment". I thought I would come back provide a list of freely available .NET projects that helped me with my own development and can be used out-of-the-box and free of charge:
ICSharpCode (WinForms)
AvalonEdit (WPF)
ScintillaNET (WinForms)
Query Commander [for example of intellisense implementation] (WinForms)
Edit B: 15 months after the question was asked I am still looking for new improved editors. This one is nice...
RoslynPAD is cool!
Edit C: 2 years+ on from the question, I have found the following projects, both using WPF and backed by AvalonEdit.
CodeCompletion for AvalonEdit using NRefactory. This project is really nice and has a full implementation of intellisense using NRefactory.
ScriptCS ScriptCS makes it easy to write and execute C# with a simple text editor.
How (in detail) do Microsoft implement their as-you-type Intellisense?
I can describe it to any level of detail you care to name, but I don't have the time for more than a brief explanation. I'll explain how we do it in Roslyn.
First, we build an immutable model of the token stream using a data structure that can efficiently represent edits, since obviously edits are precisely what there are going to be a lot of.
The key insight to making it efficient for persistent reuse is to represent the character lengths of the tokens but not their character positions in the edit buffer; remember, a token at the end of the file is going to change position on every edit but the length of the token does not change. You must at all costs minimize the number of total re-lexings if you want to be efficient on extremely large files.
Once you have an immutable model that can handle inserts and deletions to build up an immutable token stream without re-lexing the entire file every time, you then have to do the same thing, but for grammatical analysis. This is in practice a considerably harder problem. I recommend that you obtain an undergraduate or graduate degree in computer science with an emphasis on parser theory if you have not already. We obtained the help of people with PhDs who did their theses on parser theory to design this particular bit of the algorithm.
Then, obviously, build a grammatical analyzer that can analyze C#. Remember, it has to analyze broken C#, not correct C#; IntelliSense has to work while the program is in a non-compiling state. So start by coming up with modifications to the grammar that have good error-recovery characteristics.
OK, so now you've got a parser that can efficiently do grammatical analysis without re-lexing or re-parsing anything but the edited region, most of the time, which means that you can do the work between keystrokes. I forgot to mention, of course you will need to come up with some mechanism to not block the UI thread while doing all of these analyses should the analysis happen to take longer than the time between two keystrokes. The new "async/await" feature of C# 5 should help with that. (I can tell you from personal experience: be careful with the proliferation of tasks and cancellation tokens. If you are careless, it is possible to get into a state where there are tens of thousands of cancelled tasks pending, and that is not fast.)
Now that you've got a grammatical analysis you need to build a semantic analyzer. Since you are only doing IntelliSense, it does not need to be a particularly sophisticated semantic analyzer. (Our semantic analyzer must do an analysis suitable for generating code from correct programs and correct error analysis from incorrect programs.) But of course, again it has to do good semantic analysis on broken programs, which does increase the complexity considerably.
My advice is to start by building a "top level" semantic analyzer, again using an immutable model that can persist the state of the declared-in-source-code types from edit to edit. The top level analyzer deals with anything that is not a statement or expression: type declarations, directives, namespaces, method declarations, constructors, destructors, and so on. The stuff that makes up the "shape" of the program when the compiler generates metadata.
Metadata! I forgot about metadata. You'll need a metadata reader. You need to be able to produce IntelliSense on expressions that refer to types in libraries, obviously. I recommend using the CCI libraries as your metadata reader, and not Reflection. Since you are only doing IntelliSense, obviously you don't need a metadata writer.
Anyway, once you have a top-level semantic analyzer, then you can write a statement-and-expression semantic analyzer that analyzes the types of the expressions in a given statement. Pay particular attention to name lookup and overload resolution algorithms. Method type inference will be particularly tricky, especially inside LINQ queries.
Once you've got all that, an IntelliSense engine should be easy; just work out the type of the expression at the current cursor position and display a dropdown appropriately.
how hard would it be for me to create my own of the same standard?
Well, we've got a team of, call it ten people, and it'll probably take, call it five years all together to get the whole thing done from start to finish. But we have lots more to do than just the IntelliSense engine. That's maybe only 40% of the work. Oh, and half those people work on VB, now that I think about it. But those people have on average probably five or ten years experience in doing this sort of work, so they're faster at it than you will be if you've never done this before.
So let's say it should take you about ten to twenty years of full time work, working alone, to build a Roslyn-quality IntelliSense engine for C# that can do acceptably-close-to-correct analysis of large programs in the time between keystrokes.
Longer if you need to do that PhD first, obviously.
Or, you could simply use Roslyn, since that's what it's for. That'll take you probably a few hours, but you don't get the fun of doing it yourself. And it is fun!
You can download the preview release here:
http://www.microsoft.com/download/en/details.aspx?id=27746
This is an area where Microsoft typically produces great results - Microsoft developer tools really are awesome. And there is a clear commercial advantage for sales of their developer tools and for sales of Windows to having the best intellisense so it makes sense for Microsoft to devote the kind of resources Eric describes in his wonderfully detailed answer. Still, I think it's worth pointing out a few of things:
Your customers may not actually need all the features that Microsoft's implementation provides. The Microsoft solution might be incredibly over-engineered in terms of the features that you need to provide to your customers/users. Unless you're actually implementing a generic coding environment that is intended to be competitive with Visual Studio, it is likely that there are aspects of your intended use that either simplify the problem, or that allow you to make compromises on the solution that Microsoft feels they cannot make. Microsoft will likely spend resources decreasing response times that are already measured in hundreds of milliseconds. That may not be something you need to do. Microsoft is spending time on providing an API for others to use for code analysis. That's likely not part of your plan. Prioritize your features and decide what "good enough" looks like for you and your customers then estimate the cost of implementing that.
In addition to bearing the obvious costs of implementing requirements that you may not actually have, Microsoft also carries some costs that may not be obvious if you haven't worked in a team. There are huge communication costs associated with teams. It's actually incredibly easy to have five smart people take longer to produce a solution than it takes for a single smart person to produce the equivalent solution. There are aspects of Microsoft's hiring practices and organizational structure that make this scenario more likely. If you hire a bunch of smart people with egos and then empower all of them to make decisions, you too can get a 5% better solution for 500% of the cost. That 5% better solution might be profitable for Microsoft, but it could be deadly for a small company.
Going from a 1 person solution to a 5 person solution increases the costs, but that's just the intra-team development costs. Microsoft has separate teams that are devoted to (roughly) design, development, and testing even for a single feature. The project-related communication between peers across these boundaries has higher friction than within each of the disciplines. This not only increases communication costs between individuals, but it also results in larger team sizes. And more than that - since it's not a single team of 12 individuals, but is instead 3 teams of 5 individuals, there is 3x the upward communication cost. More costs that Microsoft has chosen to carry that may not translate to similar costs for other companies.
My point here is not to describe Microsoft as an inefficient company. My point is that Microsoft makes a ton of decisions about everything from hiring, to team organization, to design and implementation that start from assumptions about profitability and risk that simply do not apply to companies that are not Microsoft.
In terms of the intellisense thing, there are various ways of thinking about the problem. Microsoft is producing a very generic, reusable solution that doesn't just solve intellisense, but also targets code navigation, refactoring, and various other uses for code analysis. You don't need to do things the same way if your sole goal is to make it easy for developers to enter code without having to type much. Targeting that feature doesn't take years of effort and there are all sorts of creative things you can do if you're not just providing an API, but you actually control the UI too.
It seemed like this question should have been asked before, but searching found nothing.
I've always wondered what's the point of making us put every bit of code inside a class or interface. I seem to remember that there were some advantages to requiring a main() function like C, but nothing for classes. Languages like Python are, in a way, even more object oriented than Java since they don't have primitives, but you can put code wherever you want.
Is this some sort of "misinterpretation" of OOP? After all, you can write procedural code like you would in C and put it inside a class, but it won't be object oriented.
I think the goal of requiring that everything is enclosed in classes is to minimize the number of concepts that you need to deal with in the language. In C# or Java, you only need to understand the object-model (which is fairly complex, though). However, you only have classes with members and instances of classes (objects).
I think this is a very important goal that most of the languages try to follow in one way or another. If C# had some global code (for example to allow interactive evaluation and specification of the startup code without Main method), you'd have one additional concept to learn (top-level code). The choice made by C#/Java is of course just one way to get the simplicity.
Of course, it is a question whether this is the right choice. For example:
In functional languages, programs are structured using types (type declarations) and expressions. The body of the program is simply an expression that is evaluated, which is a lot simpler than a class with Main method and it also enables interactive scripting (as in Python).
In Erlang (and similar languages), program is structured as concurrently executing processes with one main process that starts other processes. This is a dramatically different approach, but it makes a good sense for some types of applications.
In general, every language has some way of looking at the world and modelling it and uses this point of view when looking at everything. This works well in some scenarios, but I think that none of the models is fully universal. That may be a reason why languages that mix multiple paradigms are quite popular today.
As a side-note, I think that the use of Main method is somewhat arguable choice (probably inheriting from C/C++ languages). I would suppose that more clear object-oriented solution would be to start the program by creating an instance of some Main class.
C# was not designed for "programming in the small". Rather, it was designed for component-oriented programming. That is, for programming scenarios where teams of people are developing interdependent software components that are going to be released in multiple versions over time.
The emphasis on programming-in-the-large and away from programming-in-the-small means that sometimes there is a whole lot of 'ceremony' around small programs. Using this, class that, main blah blah blah, all to write 'hello world'.
The property "a one line program is one line long" would be nice to have in C#. We're considering allowing code outside of classes in small programs as a possible feature in a hypothetical future version of C#; if you have constructive opinions pro or con on such a feature, feel free to send them to me via the contact link on my blog.
I think the idea with Java was that a top-level class would represent a single unit of code that would be compiled to a separate .class file. The idea was that these discrete, self-contained units of code could then be easily shared and combined into many projects (just as a carpenter can combine basic parts like nuts, bolts, pieces of wood, etc., to make a variety of items). The class was seen as the smallest, most basic atomic unit, and thus everything should be a part of a class to make it easier to assemble larger programs from these parts.
One can argue that object-oriented programming's promise of easily composable code didn't work out very well, but back when Java was being designed, the goal of OOP was to create little units (classes) that could easily be combined to make unique programs.
I imagine C# had some of the same goals in mind.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Straightforward C#/Java code is extremely difficult to parallelize, multi-thread, etc. As a result, straightforward C#/Java code will use less and less of the total processing power on a box (because everything is now going to be multi-core).
Solving this problem in C# and Java is not simple. Mutability and side effects are key to getting stuff done in C# and Java, but this is exactly what makes multi-core, multi-threading programming so difficult.
Hence, functional programming is going to become increasingly important.
Given that the J2EE/Ruby world will splinter amongst many functional/multi-core approaches (just like it does for just about everything else) while the .NET folks will all use F#, this line of thinking suggests that F# will be huge in two years.
What is wrong with this line of thinking? Why isn't it obvious that F# is going to be huge?
(Edit) Larry O'Brien nails it in this blog post: "Language-wise, in my opinion, this is a set of exercises where C and C++ shine — at least until the multithreading stuff. Languages with list-processing idioms will also do well initially, but may have memory-consumption issues (especially functional languages). Ultimately, I think that the managed C-derived language (Java and C#) have the easiest route to Exercise 9 and then face serious shortcomings with Exercise 10, where concurrency issues play the major role. In my opinion, concurrency is going to become the central issue in professional development in the next half-decade, so these shortcomings are very significant."
Straightforward C#/Java code is
extremely difficult to parallelize
Not if you use the Task Parallel Library.
Whether F# becomes huge depends on whether the cost/benefit is there, which is not at all obvious. If .NET developers find out that they can write some programs in 1/3 of the time using a functional rather than an imperative approach (which I think might be true for certain types of programs), then there should be some motivation for F# adoption.
Paul Graham's story of his use of Lisp in a startup company is illustrative of this process. Lisp provided them with a huge competitive advantage, yet Lisp didn't take over the world, not because it wasn't powerful, but for other reasons, like lack of library support. That F# has access to the .NET framework gives it a fighting chance.
http://www.paulgraham.com/avg.html
Functional programming is harder to get your head around than imperative programming. F# is a more difficult language in many ways than C#. Most 'developers' don't understand functional programming concepts, and can't even write very good imperative code in C#. So what hope have they got of writing good functional code in F#?
And when you consider that everybody on the team needs to be able to understand, write, debug, fix, etc. the code in the language you choose, it means you need a very strong team -- not just a very strong person -- to be able to use F# as it's meant to be used. And there aren't many of those around.
Add into the mix the fact that there's 8 years of C#/VB code lying around which is unlikely to be migrated, and that it's easier to create libraries that look and feel like the BCL in C#/VB as it's less easy to leak stuff like tuples etc. through public interfaces, and I reckon that F# will struggle to gain anything more than usage by strong teams on new, internal projects.
Ask a programming question on SO and specify you are using F#.
Ask the same question and specify you are using C#.
Compare the answers.
Using a novel programming language is a calculated risk--you may get more built-in functionality and syntactic sugar, but you will lose in community support, ability to hire programmers, and working around blind spots in the language.
I'm not picking on F#--every decision of programming language is a risk equation you need to work out. If people didn't take that risk on C#, we'd all still be using VB6 and C++ now. Same with those languages versus their predecessors. You have to decide for your project whether the advantages outweigh the risks.
There isn't really any case against F#, but you have to understand the context of the situation we, as developers, are in currently.
The multi-core architecture is still in it's infancy. The major driving force to change single-threaded apps over to a parrellel architecture is going to take time.
F# is very useful for a number of reasons, parrallelism being one of them, but not the only one. Functional programming is also extremely useful for scientific purposes. This will be huge in many sectors.
However, the way you're wording your question it sounds like you're stipulating that F# is already fighting a losing battle, which is definitely not the case. I've talked to many scientists to date that are using things such as MatLab and the like, and a lot of them are already aware of F#, and excited about it.
Imperative code is easier to write than functional code. (At least, its easier to find people who can right acceptable imperative code vs. functional code)
Some things are inherently single threaded (UI* is the best known example).
There's alot of C#/C/C++ code out there already, and multiple languages in the same project makes management of said project more difficult.
Personally, I think functional languages will become increasingly mainstream (heck F# itself is a testament to that) but probably never gain lingua franca status like C/C++/Java/C#/etc. have or will.
*This is apparently a somewhat contentious view, so I'll expand upon it.
In a multi-threaded UI, each UI event is dispatched asynchronously and on a thread of its own (the actual management of threads is probably more sophisticated than just spinning up a new one, but that's not really germane to the discussion).
Imagine if this were the case, and you're rendering the window.
The window manager asks you to draw each element (expect a message, or a function invokation for each element).
Each element reads its state (implicitly reading the application state)
Each element draws itself.
In step 2, every element MUST lock the application state (or the subset of it that affects display). Otherwise, in the event the application state is updated, the end result of rendering the window could include elements that reflect two different application states.
This is a lock convoy. Each render thread will lock, render, and then release; therefore they'll execute serially.
Now, imagine you're dealing with user input. First, users are pretty slow so the benefits are going to be non-existent unless you're doing considerable work on the (one-of-many) UI thread; so I'm going to assume thats the case.
The Window Manager informs your application of user input (once again, message, function call, whatever).
Read what's needed from the application state. (Locks needed here)
Spend noticable time crunching some numbers.
Update the application state. (Locks needed here as well)
All you've accomplished is changing from explicitly starting a worker thread, to implicitly doing so; at the cost of potential heisenbugs & deadlocks if you're loose with locking your state.
The fundamental problem with UI api's is that you're dealing with a many-to-one (or one-to-many depending on how you look at it) relationship. Either many windows, many elements, or many "input types" all of which affect a single window/surface. Some sort of synchronization has to happen, and when it does multi-threading doesn't have any benefits anymore just detractions.
What is wrong with this line of thinking? Why isn't it obvious that F# is going to be huge?
You're assuming the large masses actually write programs that need multicore support - or the programs would gain significant benefit from being parallellized. That's a false assumption.
Server side there's even less need for a parallell language.
Backend server processing already takes enough advantage of multicore/processor support by it's inherent nature of being concurrent(work is divided on clients via threads and among processes(e.g. one app server, one db server, one web container.. ).
What is wrong with this line of reasoning is that it assumes that everything will work out as planned.
There is the assumption that it will be easier to write multithreaded programs in F# than in C#. Historically, functional languages have not done all that well in popularity, and there's probably reasons why. Therefore, while it is generally easier to multithread functional than imperative languages, it's generally been easier to find people to program in imperative languages. These two things balance out somehow, depending probably on the people and the app. It may or may not be easier in general to write multithreaded applications in functional or imperative languages. It's far too early to tell.
There's the assumption that people are going to demand efficient use of their 1K-core computers. There are always applications that can take as much CPU power as they can find, but these aren't the most common applications. Most applications people run are not in any way limited by CPU power nowadays, but by delays in local I/O, networking, and users. This may change, but it won't change at all quickly.
Also, it isn't clear that massively multicore processors are the wave of the future. There may be a fairly small market for them, so chip manufacturers will produce smaller chips instead of more powerful, or will devote resources to other things that we aren't clear about right now.
There's the assumption that F# is going to be the winner among functional languages. As the VS 2010 functional language, it does have a considerable advantage. However, the race hasn't really started yet, and there's plenty of time for things to happen. It may turn out that F#.NET isn't a particularly good language to program massively parallel PCs, and something else may come about. It may happen that Microsoft and .NET won't be all that important by the time 64-core processors routinely come on cheap laptops. (Shifts like that aren't all that common, but they tend to come by surprise. They also are more likely to happen during times of conceptual change, and a mass move to functional languages would qualify.)
On the assumption that F# will continue to be the primary Microsoft functional language, that Microsoft programming languages will continue to be dominant, that getting maximum performance out of massively multicore processors will be important, that all the technical arguments won't be swamped by business inertia, and that F# will be considerably better than C# and other such languages at writing massively multithreaded applications, and that you're right. However, that's a whole lot of assumptions strung together and linked by plausible reasons rather than rigid logic.
You seem to be trying to predict the future as a combination of next year's stuff extended by one line of reasoning about technical issues, and that's extremely unreliable.
The only 'case' against it (if there is such a thing) is that most modern, professional developers use different tools (as well as different tool types). F# brings some unique tools to the game, and those of us who embrace them will find our respective, specialized talents useful for other programming tasks -- especially those tasks involving analysis and manipulation of large data collections.
What I've seen of F# truly amazes me. Every demo leaves me grinning because F# strikes me as an advanced edition of what I remember from 'the good old days' when functional programming was much more common (probably more 'old' than 'good' to be sure, but such is nostalgia).
I disagree with the premise that C# is hard to parallelize. It really isn't if you know what you're doing. Additionally, parallel linq will make this even easier. Do I wish there was an OpenMP for C#? Of course, but the tools C# provides allow you to do almost everything you want if you are good enough (and I feel one doesn't even have to be that good anymore).
There is a few things worth noting about technology
The best technical solution is not always the most popular or most used. (And I don't know if F# is any good) I would argue that SQL is the most used, most asked for programming language by employers and its not a nice,cool,fast,friendly,fun language in my book. If the best technical solution always "won", how do you explain qwerty keyboards? And if you ever read the "design" for x86/x64 processors.. ;)
Azul with 864 core servers exclusively uses Java, and the trend is bigger servers in future.
If we assume the battle is between C# and F#, I do not think F# will win over C# within 2 years for the following reasons:
The features of F# that C# does not have are not features people have been missing. For instance, I think Seq.map, Seq.iter, Seq.fold and friends are great, but I don't see a majority of developers switching from foreach to these constructs.
The performance benefits of multicores are irrelevant to most of the existing programs, as only few programs are cpu-bound. For those programs where performance really is important, (e.g. video games), C++ will remain predominant, at least for the 2 years to come. It's not that hard to use threads in C++, assuming one avoids side-effects (which you can decide to do even in C++). Isn't that what Google is doing?
For F# to become really big, I think it has to become one of the main languages used in teaching, the way Java has been. This is actually quite likely, seeing how the academic world is fond of functional languages. Should that happen, I don't think the effects will become visible before 5 years.
Linking assemblies together is not trivial.
F# is tied to the .NET typing system, which is significantly more restricted than, say, PHP. It's probably right up there with Java in the land of Strong Typing. That makes the entry barrier pretty high for someone who isn't intimately familiar with the .NET types.
Single-assignment code is hard to write; most algorithms use the typical Turing machine model, which permits multiple assignments and single-assignment code does not really neatly fit into a good model for How We Think. At least, for those of us who write Turing Machine code for a living. Perhaps it's different for those of us who write Lambda Machine code out there...
F# is tied to Microsoft, which produces knee-jerk hate from many geeks. They would rather use Lisp or Scheme or Haskell(or whatever). Although mono supports it, it doesn't support it well last time I tried to work on mono(it was quite slow).
Most of our existing code lives in imperative, sequential code bases, and most of our applications are oriented around imperative, sequential operations with side-effects.
Which is all to say, pure functional approaches do not neatly model the real world, so F# is going to have to carve out a niche where it easily manages real-world problems. It cannot be a general purpose language, because it does not neatly solve general purpose problems.
For those of you who aren't familiar with the concept, abstraction inversion is the implementation of low-level constructs on top of high-level constructs, and is generally considered a bad thing because it adds both needless complexity and needless overhead. Of course, this is a somewhat imprecise, subjective definition.
In your opinion, does programming in a single-paradigm OOP language where everything must be part of a class and things like pointers aren't exposed, such as Java or C#, inevitably lead to abstraction inversion? If so, in what cases?
Single-paradigm anything violates the First Commandment of Abstractions, which few people seem to know about and even less care about.
Thou shalt not make unto thee any abstraction that cannot be overridden if necessary, that thy code be free of ugly abstraction inversions.
No matter what your paradigm, once you start writing non-trivial code to solve real-world problems, you are going to end up with some things that just don't fit the paradigm very well. If you declare that that one paradigm is all there is, this is when things get ugly.
To mix a couple metaphors, when all you have is a mallet, everything starts to look like a peg, and if all your holes are round and you suddenly end up with some square pegs and you don't have any saws, (just mallets,) you've got yourself a problem.
There's no free lunch. Everything is a trade-off. The easier code becomes to write, the harder it becomes for someone else to read and maintain, or for you or anyone else to debug when problems occur below the level of abstraction that you're working at. (And they will eventually, because no abstraction is perfect.
This is the fundamental flaw with "helpful" technologies and paradigms such as managed code, garbage collection, JIT compilation and the "everything is an object" fiat. They impose a baseline level of abstraction that you are not allowed to reach beneath, and when something goes wrong below that level, there's nothing you can do about it. You're stuck working around a bad abstraction because you can't fix it.
real programmers can write FORTRAN in any language
in other words, it ain't the language, it's the programmer
Java and C# have static methods which are equivalent to functions, so the language isn't forcing anything on you.
That said, Once I really got OO, I haven't had any desire whatsoever to go to another style of programming.
If your simple OO layer is covering something complex, I suggest that it's probably your code that's an issue. If OO is done right it should be simple all the way down to the metal.
I don't think a language like Java or C# suffers from this in any tangible way, simply because the libraries accompanying the framework are so rich that the need to break into another paradigm isn't really required for general programming.
That said, the rich libraries themselves can suffer from abstraction inversion however, because the internal implementations are often hidden, or key classes are sealed, developers attempting to extend these libraries are often forced into re-implementing/replicating functionality to successfully make use of extension points provided by the base class library - this is not so much a language issue, as a conscious choice made by the developer of the base class libraries, to avoid exposing functionality which may be brittle or change often with new releases of the .Net Framework/JDK.
Also because the .Net Framework / Java Runtime both allow for interop with other languages sitting atop the common runtime, the ability to target other paradigms (such as functional programming, dynamic languages etc.) can also provide another route to breaking away from single paradigm constraints.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How costly is .NET reflection?
I am currently in a programming mentality that reflection is my best friend. I use it a lot for dynamic loading of content that allows "loose implementation" rather than strict interfaces, as well as a lot of custom attributes.
What is the "real" cost to using reflection?
Is it worth the effort for frequently reflected types to have cached reflection, such as our own pre-LINQ DAL object code on all the properties to table definitions?
Would the caching memory footprint outwieght the reflection CPU usage?
Reflection requires a large amount of the type metadata to be loaded and then processed. This can result in a larger memory overhead and slower execution. According to this article property modification is about 2.5x-3x slower and method invocation is 3.5x-4x slower.
Here is an excellent MSDN article outlining how to make reflection faster and where the overhead is. I highly recommend reading if you want to learn more.
There is also an element of complexity that reflection can add to the code that makes it substantially more confusing and hence difficult to work with. Some people, like Scott Hanselman believe that by using reflection you often make more problems than you solve. This is especially the case if your teams is mostly junior devs.
You may be better off looking into the DLR (Dynamic Language Runtime) if you need alot of dynamic behaviour. With the new changes coming in .NET 4.0 you may want to see if you can incorporate some of it into your solution. The added support for dynamic from VB and C# make using dynamic code very elegant and creating your own dynamic objects fairly straight forward.
Good luck.
EDIT: I did some more poking around Scott's site and found this podcast on reflection. I have not listened to it but it might be worth while.
There are lots of things you can do to speed up reflection. For example, if you are doing lots of property-access, then HyperDescriptor might be useful.
If you are doing a lot of method-invoke, then you can cache methods to typed delegates using Delegate.CreateDelegate - this then does the type-checking etc only once (during CreateDelegate).
If you are doing a lot of object construction, then Delegate.CreateDelegate won't help (you can't use it on a constructor) - but (in 3.5) Expression can be used to do this, again compiling to a typed delegate.
So yes: reflection is slow, but you can optimize it without too much pain.
With great power comes great responsibility.
As you say, reflection has costs associated with it, and depending on how much reflection you do it can slow the application down significantly.
One of the very approrpiate places to use it is for IoC (Inversion of Control) since, depending on the size of your application, would probably have more benefits than not.
Thanks for the great links and great comments, especially on the part of the Jr Devs, that hit it right on the money.
For us it is easier for our junior developers to do this:
[TableName("Table")]
public class SomeDal : BaseDal
{
[FieldName("Field")]
public string Field
}
rather than some larger impelementations of DAL. This speeds up their building of the DAL objects, while hiding all the internal workings for the senior developers to gut out.
Too bad LINQ didn't come out earlier, I feel at times we wrote half of it.
One thing that can sometimes bite you when using reflection is not updating calls using reflection when doing refactoring. Tools like resharper will prompt you to update comments and strings when you change a method name, so you can catch most of them that way, but when you're calling methods that have been dynamically generated or the method name has been dynamically generated you might miss something.
The only solution is good documentation and thorough unit testing.