C# coding – I’m getting lazy

Microsoft continues their effort to reduce the amount of code required for C# developers to accomplish certain tasks. The more I see of this the more I want. Somewhere between where we are now and the point where the system reads our minds and just does what we want, there is a place where guys like me can get the system to deal with housekeeping that’s time consuming and boring to code. I’m looking for that place…

Consider this code:

if ( Foo(blah) != null )
return Foo(blah);

That requires two calls to Foo. We can simplify that as:

using (result = Foo(blah))
{
  if ( result != null )
    return result;
}

But we needed to create an object to hold a temporary result and the code gets a little bloated. In line with some of the changes in C# v3.5, it would be nice if we could do something like this:

if ( Foo(blah) != null )
    return MethodResult;

In that case, MethodResult is the result of the last method executed, properly cased as the Foo return type. The compiler would need to use reflection to handle this but reflection is being done on the entire code set for other purposes anyway.

This comes up a LOT and it seems like a waste of time to write code where we should be able to say to the compiler "you know what I mean and I know what I mean and I don’t want to write the same grunt code every time I do this, so I want you to do it for me from now on".

Similarly, consider this:

try { Foo(blah1); } catch {}
try { Foo(blah2); } catch {}
try { Foo(blah3); } catch {}

In this case, we really don’t care if we’re throwing exceptions but we want to make sure that every statement gets executed. C# doesn’t have the BASIC equivalent of ON ERROR RESUME NEXT. One way to handle this is to modify Foo, or we can wrap it:

Object TryFoo(Object Blah) { try { Foo(blah1); } catch {} }

then:

TryFoo(blah1);
TryFoo(blah2);
TryFoo(blah3);

Again, we’re in an area where we know what we want to do and we shouldn’t need to use a pattern to get the compiler to recognize it.

I guess another way to do the above would be something like this:

Object[] Params = new Object[] { blah1, blah2, blah3 };
TryFoo(Params);

Then (code omitted) TryFoo would just need to loop through the array like this:

foreach (Object param in Params) {
  try { Foo(param); } catch {}
}

As we see, there are various ways to accomplish this. The point is that I don’t want to write a lot of code to make it happen. I’d like to use some very simple, almost transparent syntax to tell the CLR to ignore errors until I say it’s OK to throw exceptions again. (No, having Attributes decorating statements is not my idea of transparent syntax.) How about options on the Try?

try ( TryOptions.IgnoreAll) {
  Foo(blah1);
  Foo(blah2);
} finally {}

Let’s say Microsoft sees this and says "hey, that’s great, it will be in v4.1". That doesn’t solve the core point I have here that 1) we need to extend the language to accomplish specific tasks, and 2) doing so is a major chore. By making it easy to extend language syntax we can get what we want fast and share ideas with peers about what works best. Then Microsoft can implement permanent enhancements for ideas that work well for everyone.

The approach used for some tools in other environments is to put some sort of marker into the code, let a pre-processor swap code for the marker, do the compile, then remove the generated code. That’s not the right way to do it with .NET languages because we can’t debug it if the source and object don’t match. So the real solution is to get the environment to do this natively.

I need to get some experience with the before/after compile functions, generating code, etc. Rather than attempting to extend the compiler itself to generate code at compile time (yeah, that’ll happen), it seems VS already has the tools to do this. Sure I can create snippets or even use something like CodeSmith to generate the code, but the idea is to reduce the code and get the system to do the work, while minimizing the amount of code we need to debug. There are so many places where this would be of value.

Until the language is extensible I guess for now I’ll have to be content with code generation. Tools like CodeSmith have a cost and a learning curve. Snippets have a learning curve and no cost. So if I have time for anything I guess it will have to be snippets. If I get time to write up what I’m talking about here, I’ll post something. Considering the time it takes to learn, code, and document, I’m guessing you shouldn’t hold your breath for this one.

Leave a Reply