views:

111

answers:

4

I hate writing code that makes my software more solid. This is something the framework should have done! So, is anybody aware of a code "enhancing" utility that solidifies the code?

If I had to create something like this myself, it would work as follows: When you're compiling your code with a Debug flag, it would auto-magically add "solidifying" code for each method:

Warp the code with a try-catch and put a Debug.Assert(true) in the catch (so that exceptions are caught at their origin).

Log each method's entry, printing "ToString()" values of arguments, so I can trace what's going on.

Check each argument for null.

Use an "IsValid" framework to check the object itself and each argument, where IsValid() is the object's way of declaring that its expectations are true (for example, if I'm a TableOfContentsEntry I expect to always be in a Book that's IsValid() and to point to a Page that's IsValid().

So, why not?

A: 

I doubt there is something like that and if, then it sure isn't that usable. It depends on your rules definitions, different people think different, have different needs and frameworks... The things you described could be achieved by metaprogramming or some macro system. In Java, there are some projects which could help to implement such an approach usign annotations, don't know if there is some equivalent in C# universe. The isValid() functionality however looks pretty much like design by contract idea, maybe there are some frameworks for that.

Gabriel Ščerbák
I saw a "rough cut" (i.e. preview) of "Practical Code Generation in .NET" by Peter Vogel on Safari Books Online, and I started thinking why would one generate code, and then I thought that getting rid of this validity checking manual-labor would be a great use, so I wonder if anyone is doing it.And re "rules/definition" etc. - this has been solved by static code analysis and rule enforcing tools such as FxCop - obviously, such a framework must be configurable.
Avi
Don't forget, that static analysis just uses some metrics, but doesn't prove anything, if it did it would be part of the compilers.Code generation sure is one way.
Gabriel Ščerbák
+1  A: 

It's nice to see my book being plugged! The big issue for me is that I think that code generation should aim to be "beside" the developer's code--i.e. ideally, the generated code wouldn't be intermixed with the developer's code. I wonder if there's any way to add this 'solidfying' code as a partial class or as a proxy that would set between the class and the client that was calling it? Of course, it's certainly possible to generate the code and insert it into the developer's code but you'd want to create some sort of convention so that when the developer makes a change and regenerates the "soldifying" code,the tool could delete the old code and generate new code based on the latest version of the developer's code.

Peter Vogel
+1  A: 

I would love something that doesn't lose your stack when you pass something off to a worker thread. I don't even know of a workaround for this (C#). Would be great to know the stack of the parent thread up to the point where the worker thread was created.

In general I think a lot of the really useful stuff would need to be built into a language and can't really be achieved cleanly by a library or framework alone. I remember in high school they taught to always write in pre/post conditions in the comments for a function, but what I'd really like to see is writing pre/post conditions that are checked if possible at compile time, if not then at runtime. They'd be flagged some way such that an editor can optionally show or hide them so it doesn't get in the way of reading the real code.

Davy8
+1  A: 

If you want to log method calls, you could use an AOP framework like PostSharp. Things like enforcing method pre/postconditions would be best achieved using design-by-contract mechanisms like the new Code Contracts library which will ship with .net4.0. It certainly doesn't make sense to just check arguments for null since this may be a valid value depending on the method. Injecting Debug.Asserts into code could be problematic since you may not want to/be able to handle exceptions in the source function. I think it would be impractical if not impossible to create a generic framework for this sort of thing since requirements will differ so greatly between projects.

EDIT: To clarify my comment about adding debug assertions into methods - I read your proposal to be to convert a method body into something like this:

public void SomeMethod(args)
{
    try
    {
        //original method body
    }
    catch(Exception ex)
    {
        Debug.Assert(false);
        throw;
    }
}

The problem with this is that Asserts indicate things that should never be false - so this construct means that the method can never throw which isn't true in general. The problem is now that if the method does throw, the assertion will fail even if the calling method handles the exception appropriately. From your comment it seems that you are doing something like this:

public void SomeMethod(object arg)
{
    Debug.Assert(arg != null);
    if(arg == null) throw new ArgumentNullException("arg");

    //rest of method
}

This is a useful practice, and I believe that the code contracts library supports 'legacy' precondition checking (throwing exceptions) in its static analysis.

Lee
Thanks - great references, willlook into them.IMHO Debug.Assert does not raise an exception, and it provides the important benefit of stopping the execution "near" the point where a problem is detected. The problem is that it "dies" at runtime, and if an error occurs it is left unhanlded. So what I started doing is:#region ArgCheckbool badCond=(theArgument == null) //for exampleDebug.Assert(!badCond);if(badCond) throw new ArgumentNullException();#endregion ArgCheckThe poor programmer's solution. But it annoys me that stepping through this code expands the region.
Avi