Any way to create a compile time timebomb to guard test-code? - c#

Problem Description:
As a single developer I've stumbled across this several times:
Sometimes on a project instead of choosing a cleaner approach it makes sense for efficiency reasons to just add some quick and dirty test-code within production code.
While it may sound like a dirty solution, please keep in mind, that I'm only talking about test-code that should be thrown away anyway, when I just want to quickly check something.
To be 100% sure to not forget to take this code out again I'd like to guard it by a compile time timebomb:
What I mean is some piece of code, preprocessor code or anything basically that allows for compilation for a certain timespan, like half an hour for instance and then automatically results in a compiler error after the time (half an hour) is over. A compiler error would be great because it could directly mark the place of the test-code. (I could have it as the first line(s) within such a throwaway region for instance)
So anything like "throw an error if system time is bigger than this specific DateTime" would be great.
I looked into the preprocessor (not too familiar with it) but the directives #if and #error didn't seem like an option since #if expects a symbol instead of an expression.
Question:
Is such a timebomb possible? Any idea on how to do that?
Or any idea on how to get the efficiency of quick and dirty test-code and be absolutely sure that taking it out again can't be forgotten?
(A run time error would be easy but if a compile time error isn't possible I would need something of a similar quality to it.)

I personally think, that timebombing is the wrong approach. Use build targets to distinguish different purpose of code usage.
// Constructor call will only be allowed for target DEBUG
public class Protect : IDisposable
{
#if DEBUG
[Obsolete("error", false)]
#else
[Obsolete("error", true)]
#endif
public Protect()
{
}
public void Dispose()
{
}
}
Usage
using (new Protect())
{
// do some testcode
// will only compile in DEBUG mode
}

One option is to generate file that has "current time" variable at build time and than simply add check that code should stop working after particular time.
Possible approach to generate file at build time - how to put computed value in RESX at build time C#

Related

Block code execution at it's root

What i want to do
I'm trying to write optimized function caller which execution can be optional, which can be defined before compilation. without the user specifying at the start should it be executed of not.
Possible solutions
First is to use #define directives. The bad thing is the they would have to be added and closed for every LogMessage call, which is what i dont want to use.
Second solution is to use [Conditional("")] but that would also require adding it before every function call.
Is to use directives inside function block, but that would sacrifice performance. About this more in the example.
Example
Consider this example. It does everything I want - user calls LogMessage("whatever") and before compilation i specify should it be executed in the build.
LogMessage("whatever");
public static void LogMessage(string message){
#if LOG
///execute log
#endif
}
Problem is that string "whatever" is created before - regardless of will it be executed or not. I dont want to allow string creation and/or construction such as LogMessage(someNUmber+" is "+otherNumber); if should not happen.
Final Point
Im trying to find solution in which LogMessage would be canceled - blocked at it's root, without adding directives before. I was thinking maybe some sort of reflection search before compilation would do it, but im not really sure.
Thanks,
I hope somebody can shed some light in the right direction.

Entity Framework 6 - Enforce asynchronous queries, compile time prevent synchronous calls

With the move to EF6.1, our goal is to use exclusivity the Async/Await options speaking with our data sets. While porting from our previous Linq2Sql, there are many .ToList(), .FirstOrDefault(), and .Count()'s. I know we can search and fix those all, but it would be nice if we could, at compile time, prevent those functions from even being permitted into a build. Does anyone have have a creative idea on how to accomplish this? Even if they were compiler warnings that could be thrown (such as use of the Obsolete attribute).
You can use the .NET Compiler Platform to write a Diagnostic and Code Fix that will look for these patterns and provide warnings/errors.
You could even implement a Syntax Transformation to automatically change these constructs - though the effort might be more expensive than just doing it by hand.
Following up to this... i never found a solution that can detect this at compile time, but I was able to do this in code in the DataContext:
public EfMyCustomContext(string connctionString)
: base(string.Format(CONNECTION_STRING, connctionString))
{
#if DEBUG
this.Database.Log = LogDataBaseCall;
#endif
}
#if DEBUG
private void LogDataBaseCall(string s)
{
if (s.Contains("Executing "))
{
if (!s.Contains("asynchronously"))
{
// This code was not executed asynchronously
// Please look at the stack trace, and identify what needs
// to be loaded. Note, an entity.SomeOtherEntityOrCollection can be loaded
// with the eConnect API call entity.SomeOtherEntityOrCollectionLoadAsync() before using the
// object that is going to hit the sub object. This is the most common mistake
// and this breakpoint will help you identify all synchronous code.
// eConnect does not want any synchronous code in the code base.
System.Diagnostics.Debugger.Break();
}
}
}
#endif
Hope this helps someone else, and still would love if there was some option during compile.

Is '#IF DEBUG' deprecated in modern programming?

This is my first StackOverflow question so be nice! :-)
I recently came across the following example in some C# source code:
public IFoo GetFooInstance()
{
#IF DEBUG
return new TestFoo();
#ELSE
return new Foo();
#ENDIF
}
Which lead me to these questions:
Is the use of "#IF DEBUG" unofficially deprecated? If not what is considered to be a good implementation of its use?
Using a class factory and/or tools like MOQ, RhinoMocks, etc how could the above example be implemented?
Using an IoC container, the entire function becomes redundant, instead of calling GetFooInstance you'd have code similar to:
ObjectFactory.GetInstance<IFoo>();
The setup of your IoC container could be in code or through a configuration file.
Nope. We use it all the time to sprinkle diagnostic information in our assemblies. For example I have the following shortcut used when debugging:
#if DEBUG
if( ??? ) System.Diagnostics.Debugger.Break();
#endif
Where I can change ??? to any relevant expresion like Name == "Popcorn". etc. This ensures that none of the debugging code leaks into the release build.
Just like some of the other posters have mentioned, I use #if statements all the time for debugging scenarios.
The style of code that you have posted is more of a factory creation pattern, which is common. I use it frequently, and not only do I not consider it depreciated, I consider the use of #if and #define statements to be an important tool in my bag of tricks.
I believe CastleWindsor (http://www.castleproject.org/container/index.html) also has an IoC container. I believe the general pattern is that in the configuration file, you state that TestFoo or IFoo will be the class created when CastleWindsor initializes the IoC container.
Yes. I would strongly advise AGAINST using "#IF DEBUG" except in rare circumstances
It was common place in C, but you should not use in a modern language such as C# for several reasons:
Code (and header) files become nightmarish
It is too easy to make a mistake and leave in/out a conditional for a Release build
Testing becomes a nightmare: need to test many combinations of builds
Not all code is compile checked, unless you compile for ALL possible
conditional symbols!
#Richard's answer shows how you can replace using IoC (much cleaner).
I strongly deprecate #if; instead use if with a manifest constant:
#define DEBUG 0 // actually in a header or on a command line
public IFoo GetFooInstance()
{
if (DEBUG)
return new TestFoo();
else
return new Foo();
}
Why is #IF bad? Because in the #IF version, not all code is typechecked. For complicated, long-lived codes, bitrot can set in, and then suddenly you need DEBUG but the code won't build. With the if version, the code always builds, and given even the most minimal optimization settings, your compiler will completely eliminate the unreachable code. In other words, as long as DEBUG is known to be always 0 (and #define will do that for you), there is no run-time cost to using if.
And you are guaranteed that if you change DEBUG from 0 to 1, the system will build.
Your compiler should be smart enough to figure out that:
final DEBUG=false;
...
if(DEBUG)
return new debugMeh();
else
return new meh();
the method never has to be called and can, in fact, be compiled out of the final assembly.
That plus the fact that even the unoptimized performance difference wouldn't amount to anything significant makes using some different syntax mostly unnecessary.
EDIT: I'd like to point out something interesting here. Someone in comments just said that this:
#IF DEBUG
return new TestFoo();
#ELSE
return new Foo();
#ENDIF
was easier to write than this:
if(DEBUG)
return new TestFoo();
else
return new Foo();
I find it really amazing the lengths that people will go to to defend the way they've done things as correct. Another said that they would have to define a DEBUG variable in each file. I'm not sure about C#, but in Java we generally put a
public static final DEBUG=true;
in our logger or another central factory object (although we actually find better ways to do this--such as using DI).
I'm not saying the same facilities don't exist in C#, I'm just amazed at the lengths people will go to to prove the solution they hold onto because of habit is correct.

How do you flag code so that you can come back later and work on it?

In C# I use the #warning and #error directives,
#warning This is dirty code...
#error Fix this before everything explodes!
This way, the compiler will let me know that I still have work to do. What technique do you use to mark code so you won't forget about it?
Mark them with // TODO, // HACK or other comment tokens that will show up in the task pane in Visual Studio.
See Using the Task List.
Todo comment as well.
We've also added a special keyword NOCHECKIN, we've added a commit-hook to our source control system (very easy to do with at least cvs or svn) where it scans all files and refuses to check in the file if it finds the text NOCHECKIN anywhere.
This is very useful if you just want to test something out and be certain that it doesn't accidentaly gets checked in (passed the watchful eyes during the diff of everything thats commited to source control).
I use a combination of //TODO: //HACK: and throw new NotImplementedException(); on my methods to denote work that was not done. Also, I add bookmarks in Visual Studio on lines that are incomplete.
//TODO: Person's name - please fix this.
This is in Java, you can then look at tasks in Eclipse which will locate all references to this tag, and can group them by person so that you can assign a TODO to someone else, or only look at your own.
If I've got to drop everything in the middle of a change, then
#error finish this
If it's something I should do later, it goes into my bug tracker (which is used for all tasks).
'To do' comments are great in theory, but not so good in practice, at least in my experience. If you are going to be pulled away for long enough to need them, then they tend to get forgotten.
I favor Jon T's general strategy, but I usually do it by just plain breaking the code temporarily - I often insert a deliberately undefined method reference and let the compiler remind me about what I need to get back to:
PutTheUpdateCodeHere();
An approach that I've really liked is "Hack Bombing", as demonstrated by Oren Eini here.
try
{
//do stuff
return true;
}
catch // no idea how to prevent an exception here at the moment, this make it work for now...
{
if (DateTime.Today > new DateTime(2007, 2, 7))
throw new InvalidOperationException("fix me already!! no catching exceptions like this!");
return false;
}
Add a test in a disabled state. They show up in all the build reports.
If that doesn't work, I file a bug.
In particular, I haven't seen TODO comments ever decrease in quantity in any meaningful way. If I didn't have time to do it when I wrote the comment, I don't know why I'd have time later.
//TODO: Finish this
If you use VS you can setup your own Task Tags under Tools>Options>Environment>Task List
gvim highlights both "// XXX" and "// TODO" in yellow, which amazed me the first time I marked some code that way to remind myself to come back to it.
I'm a C++ programmer, but I imagine my technique could be easily implemented in C# or any other language for that matter:
I have a ToDo(msg) macro that expands into constructing a static object at local scope whose constructor outputs a log message. That way, the first time I execute unfinished code, I get a reminder in my log output that tells me that I can defer the task no longer.
It looks like this:
class ToDo_helper
{
public:
ToDo_helper(const std::string& msg, const char* file, int line)
{
std::string header(79, '*');
Log(LOG_WARNING) << header << '\n'
<< " TO DO:\n"
<< " Task: " << msg << '\n'
<< " File: " << file << '\n'
<< " Line: " << line << '\n'
<< header;
}
};
#define TODO_HELPER_2(X, file, line) \
static Error::ToDo_helper tdh##line(X, file, line)
#define TODO_HELPER_1(X, file, line) TODO_HELPER_2(X, file, line)
#define ToDo(X) TODO_HELPER_1(X, __FILE__, __LINE__)
... and you use it like this:
void some_unfinished_business() {
ToDo("Take care of unfinished business");
}
It's not a perfect world, and we don't always have infinite time to refactor or ponder the code.
I sometimes put //REVIEW in the code if it's something I want to come back to later. i.e. code is working, but perhaps not convinced it's the best way.
// REVIEW - RP - Is this the best way to achieve x? Could we use algorithm y?
Same goes for //REFACTOR
// REFACTOR - should pull this method up and remove near-dupe code in XYZ.cs
I use // TODO: or // HACK: as a reminder that something is unfinished with a note explaining why.
I often (read 'rarely') go back and finish those things due to time constraints.
However, when I'm looking over the code I have a record of what was left uncompleted and more importantly WHY.
One more comment I use often at the end of the day or week:
// START HERE CHRIS
^^^^^^^^^^^^^^^^^^^^
Tells me where I left off so I can minimize my bootstrap time on Monday morning.
// TODO: <explanation>
if it's something that I haven't gotten around to implementing, and don't want to forget.
// FIXME: <explanation>
if it's something that I don't think works right, and want to come back later or have other eyes look at it.
Never thought of the #error/#warning options. Those could come in handy too.
I use //FIXME: xxx for broken code, and //CHGME: xxx for code that needs attention but works (perhaps only in a limited context).
Todo Comment.
These are the three different ways I have found helpful to flag something that needs to be addressed.
Place a comment flag next to the code that needs to be looked at. Most compilers can recognize common flags and display them in an organized fashion. Usually your IDE has a watch window specifically designed for these flags. The most common comment flag is: //TODO This how you would use it:
//TODO: Fix this before it is released. This causes an access violation because it is using memory that isn't created yet.
One way to flag something that needs to be addressed before release would be to create a useless variable. Most compilers will warn you if you have a variable that isn't used. Here is how you could use this technique:
int This_Is_An_Access_Violation = 0;
IDE Bookmarks. Most products will come with a way to place a bookmark in your code for future reference. This is a good idea, except that it can only be seen by you. When you share your code most IDE's won't share your bookmarks. You can check the help file system of your IDE to see how to use it's bookmarking features.
I also use TODO: comments. I understand the criticism that they rarely actually get fixed, and that they'd be better off reported as bugs. However, I think that misses a couple points:
I use them most during heavy development, when I'm constantly refactoring and redesigning things. So I'm looking at them all the time. In situations like that, most of them actually do get addressed. Plus it's easy to do a search for TODO: to make sure I didn't miss anything.
It can be very helpful for people reading your code, to know the spots that you think were poorly written or hacked together. If I'm reading unfamiliar code, I tend to look for organizational patterns, naming conventions, consistent logic, etc.. If that consistency had to be violated one or two times for expediency, I'd rather see a note to that effect. That way I don't waste time trying to find logic where there is none.
If it's some long term technical debt, you can comment like:
// TODO: This code loan causes an annual interest rate of 7.5% developer/hour. Upfront fee as stated by the current implementation. This contract is subject of prior authorization from the DCB (Developer's Code Bank), and tariff may change without warning.
... err. I guess a TODO will do it, as long as you don't simply ignore them.
This is my list of temporary comment tags I use:
//+TODO Usual meaning.
//+H Where I was working last time.
//+T Temporary/test code.
//+B Bug.
//+P Performance issue.
To indicate different priorities, e.g.: //+B vs //+B+++
Advantages:
Easy to search-in/remove-from the code (look for //+).
Easy to filter on a priority basis, e.g.: search for //+B to find all bugs, search for //+B+++ to only get high priority ones.
Can be used with C++, C#, Java, ...
Why the //+ notation? Because the + symbol looks like a little t, for temporary.
Note: this is not a Standard recommendation, just a personal one.
As most programmers seem to do here, I use TODO comments. Additionally, I use Eclipse's task interface Mylyn. When a task is active, Mylyn remembers all resources I have opened. This way I can track
where in a file I have to do something (and what),
in which files I have to do it, and
to what task they are related.
Besides keying off the "TODO:" comment, many IDE's also key off the "TASK:" comment. Some IDE's even let you configure your own special identifier.
It is probably not a good idea to sprinkle your code base with uninformative TODOs, especially if you have multiple contributors over time. This can be quite confusing to the newcomers. However, what seems to me to work well in practice is to state the author and when the TODO was written, with a header (50 characters max) and a longer body.
Whatever you pack into the TODO comments, I'd recommend to be systematic in how you track them. For example, there is a service that examines the TODO comments in your repository based on git blame (http://www.tickgit.com).
I developed my own command-line tool to enforce the consistent style of the TODO comments using ideas from the answers here (https://github.com/mristin/opinionated-csharp-todos). It was fairly easy to integrate it into the continuous integration so that the task list is re-generated on every push to the master.
It also makes sense to have the task list separate from your IDE for situations when you discuss the TODOs in a meeting with other people, when you want to share it by email etc.

break whenever a file (or class) is entered

In Visual Studio, is there any way to make the debugger break whenever a certain file (or class) is entered? Please don't answer "just set a breakpoint at the beginning of every method" :)
I am using C#.
Macros can be your friend. Here is a macro that will add a breakpoint to every method in the current class (put the cursor somewhere in the class before running it).
Public Module ClassBreak
Public Sub BreakOnAnyMember()
Dim debugger As EnvDTE.Debugger = DTE.Debugger
Dim sel As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
Dim editPoint As EnvDTE.EditPoint = sel.ActivePoint.CreateEditPoint()
Dim classElem As EnvDTE.CodeElement = editPoint.CodeElement(vsCMElement.vsCMElementClass)
If Not classElem Is Nothing Then
For Each member As EnvDTE.CodeElement In classElem.Children
If member.Kind = vsCMElement.vsCMElementFunction Then
debugger.Breakpoints.Add(member.FullName)
End If
Next
End If
End Sub
End Module
Edit: Updated to add breakpoint by function name, rather than file/line number. It 'feels' better and will be easier to recognise in the breakpoints window.
You could start by introducing some sort of Aspect-Oriented Programming - see for instance
this explanation - and then put a breakpoint in the single OnEnter method.
Depending on which AOP framework you choose, it'd require a little decoration in your code and introduce a little overhead (that you can remove later) but at least you won't need to set breakpoints everywhere. In some frameworks you might even be able to introduce it with no code change at all, just an XML file on the side?
Maybe you could use an AOP framework such as PostSharp to break into the debugger whenever a method is entered. Have a look at the very short tutorial on this page for an example, how you can log/trace whenever a method is entered.
Instead of logging, in your case you could put the Debugger.Break() statement into the OnEntry-handler. Although, the debugger would not stop in your methods, but in the OnEntry-handler (so I'm not sure if this really helps).
Here's a very basic sample:
The aspect class defines an OnEntry handler, which calls Debugger.Break():
[Serializable]
public sealed class DebugBreakAttribute : PostSharp.Laos.OnMethodBoundaryAspect
{
public DebugBreakAttribute() {}
public DebugBreakAttribute(string category) {}
public string Category { get { return "DebugBreak"; } }
public override void OnEntry(PostSharp.Laos.MethodExecutionEventArgs eventArgs)
{
base.OnEntry(eventArgs);
// debugger will break here. Press F10 to continue to the "real" method
System.Diagnostics.Debugger.Break();
}
}
I can then apply this aspect to my class, where I want the debugger to break whenever a method is called:
[DebugBreak("DebugBreak")]
public class MyClass
{
public MyClass()
{
// ...
}
public void Test()
{
// ...
}
}
Now if I build and run the application, the debugger will stop in the OnEntry() handler whenever one of the methods of MyClass is called. All I have to do then, is to press F10, and I'm in the method of MyClass.
Well, as everyone is saying, it involves setting a breakpoint at the beginning of every method. But you're not seeing the bigger picture.
For this to work at all, a breakpoint has to be set at the beginning of every method. Whether you do it manually, or the debugger does it automatically, those breakpoints must be set for this to work.
So, the question really becomes, "If there enough of a need for this functionality, that it is worth building into the debugger an automatic means of setting all those breakpoints?". And the answer is, "Not Really".
This feature is implemented in VS for native C++. crtl-B and specify the 'function' as "Classname::*", this sets a breakpoint at the beginning of every method on the class. The breakpoints set are grouped together in the breakpoints window (ctrl-alt-B) so they can be enabled, disabled, and removed as a group.
Sadly the macro is likely the best bet for managed code.
This works fine in WinDbg:
bm exename!CSomeClass::*
(Just to clarify, the above line sets a breakpoint on all functions in the class, just like the OP is asking for, without resorting to CRT hacking or macro silliness)
You could write a Visual Studio macro that obtained a list of all of the class methods (say, by reading the .map file produced alongside the executable and searching it for the proper symbol names (and then demangling those names)), and then used Breakpoints.add() to programmatically add breakpoints to those functions.
System.Diagnostics.Debugger.Break();
(at the beginning of every method)
No. Or rather, yes, but it involves setting a breakpoint at the beginning of every method.
Use Debugger.Break(); (from the System.Diagnostics namespace)
Put it at the top of each function you wish to have "broken"
void MyFunction()
{
Debugger.Break();
Console.WriteLine("More stuff...");
}
Isn't the simplest method to get closest to this to simply set a break point in the constructor (assuming you have only one - or each of them in the case of multiple constructors) ?
This will break into debugging when the class is first instantiated in the case of a non-static constructor, and in the case of a static constructor/class, you'll break into debugging as soon as Visual Studio decides to initialize your class.
This certainly prevents you from having to set a breakpoint in every method within the class.
Of course, you won't continue to break into debugging on subsequent re-entry to the class's code (assuming you're using the same instantiated object the next time around), however, if you re-instantiate a new object each time from within the calling code, you could simulate this.
However, in conventional terms, there's no simple way to set a single break point in one place (for example) and have it break into debugging every time a class's code (from whichever method) is entered (as far as I know).
Assuming that you're only interested in public methods i.e. when the class methods are called "from outside", I will plug Design by Contract once more.
You can get into the habit of writing your public functions like this:
public int Whatever(int blah, bool duh)
{
// INVARIANT (i)
// PRECONDITION CHECK (ii)
// BODY (iii)
// POSTCONDITION CHECK (iv)
// INVARIANT (v)
}
Then you can use the Invariant() function that you will call in (i) and set a breakpoint in it. Then inspect the call stack to know where you're coming from. Of course you will call it in (v), too; if you're really interested in only entry points, you could use a helper function to call Invariant from (i) and another one from (v).
Of course this is extra code but
It's useful code anyway, and the structure is boilerplate if you use Design by Contract.
Sometimes you want breakpoints to investigate some incorrect behaviour eg invalid object state, in that case invariants might be priceless.
For an object which is always valid, the Invariant() function just has a body that returns true. You can still put a breakpoint there.
It's just an idea, it admittedly has a footstep, so just consider it and use it if you like it.
Joel, the answer seems to be "no". There isn't a way without a breakpoint at every method.
To remove the breakpoints set by the accepted answer add another macro with the following code
Public Sub RemoveBreakOnAnyMember()
Dim debugger As EnvDTE.Debugger = DTE.Debugger
Dim bps As Breakpoints
bps = debugger.Breakpoints
If (bps.Count > 0) Then
Dim bp As Breakpoint
For Each bp In bps
Dim split As String() = bp.File.Split(New [Char]() {"\"c})
If (split.Length > 0) Then
Dim strName = split(split.Length - 1)
If (strName.Equals(DTE.ActiveDocument.Name)) Then
bp.Delete()
End If
End If
Next
End If
End Sub
Not that I'm aware of. The best you can do is to put a breakpoint in every method in the file or class. What are you trying to do? Are you trying to figure out what method is causing something to change? If so, perhaps a data breakpoint will be more appropriate.
You could write a wrapper method through which you make EVERY call in your app. Then you set a breakpoint in that single method. But... you'd be crazy to do such a thing.
You could put a memory break point on this, and set it to on read. I think there should be a read most of the time you call a member function. I'm not sure about static functions.
you can use the following macro:
#ifdef _DEBUG
#define DEBUG_METHOD(x) x DebugBreak();
#else
#define DEBUG_METHOD(x) x
#endif
#include <windows.h>
DEBUG_METHOD(int func(int arg) {)
return 0;
}
on function enter it will break into the debugger
IF this is C++ you are talking about, then you could probably get away with, (a hell of a lot of work) setting a break point in the preamble code in the CRT, or writing code that modifies the preamble code to stick INT 3's in there only for functions generated from the class in question... This, BTW, CAN be done at runtime... You'd have to have the PE file that's generated modify itself, possibly before relocation, to stick all the break's in there...
My only other suggestion would be to write a Macro that uses the predefined macro __FUNCTION__, in which you look for any function that's part of the class in question, and if necessary, stick a
__asm { int 3 }
in your macro to make VS break... This will prevent you from having to set break points at the start of every function, but you'd still have to stick a macro call, which is a lot better, if you ask me. I think I read somewhere on how you can define, or redefine the preamble code that's called per function.. I'll see what I can find.
I would think I similar hack could be used to detect which FILE you enter, but you STILL have to place YOUR function macro's all over your code, or it will never get called, and, well, that's pretty much what you didn't want to do.
If you are willing to use a macro then the accepted answer from this question
Should be trivially convertible to you needs by making the search function searching for methods, properties and constructors (as desired), there is also quite possibly a way to get the same information from the the ide/symbols which will be more stable (though perhaps a little more complex).
You can use Debugger.Launch() and Debugger.Break() in the assembly System.Diagnostics
Files have no existence at runtime (consider that partial classes are no different -- in terms of code -- from putting everything in a single file). Therefore a macro approach (or code in every method) is required.
To do the same with a type (which does exist at runtime) may be able to be done, but likely to be highly intrusive, creating more potential for heisenbugs. The "easiest" route to this is likely to be making use of .NET remoting's proxy infrastructure (see MOQ's implementation for an example of using transparent proxy).
Summary: use a macro, or select all followed by set breakpoint (ctrl-A, F9).
Mad method using reflection. See the documentation for MethodRental.SwapMethodBody for details. In pseudocode:
void SetBreakpointsForAllMethodsAndConstructorsInClass (string classname)
{
find type information for class classname
for each constructor and method
get MSIL bytes
prepend call to System.Diagnostics.Debugger.Break to MSIL bytes
fix up MSIL code (I'm not familiar with the MSIL spec. Generally, absolute jump targets need fixing up)
call SwapMethodBody with new MSIL
}
You can then pass in classname as a runtime argument (via the command line if you want) to set breakpoints on all methods and constructors of the given class.

Categories