Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Consider the following (Microsoft-sanctioned) code: <% using (Html.Form<HomeCont

ID: 639809 • Letter: C

Question

Consider the following (Microsoft-sanctioned) code:

<% using (Html.Form<HomeController>(action=>action.Index())) { %>

    <input type="text" id="search" />

    <input type="button" value="Submit" />

<% } %>
The using statement has but one purpose here: to add a </form> tag to the end of the generated HTML.

This feels dirty to me, for what I hope are obvious reasons:

It's not using's raison d'etre.
It deliberately causes side-effects.
It's not intuitive that Html.Form would implement IDisposable.
The using statement is not actually required, but Html.Form will break without it (unless you emit </form> yourself, which kinda misses the whole point).
This is not the only abuse that people have heaped onto the using pattern.

The question is, is there a viable alternative that provides the same stylistic/readability benefits as using, without making you feel like taking a shower afterwards?

Explanation / Answer

No, not in .NET currently.

using (by design) is the only thing that's guaranteed to have that sort of deterministic two-part execution that you can actually work with. (lock does too, but it doesn't expose anything you can hook into - and would be dirtier)

AoP solutions can maybe help, but I've not seen any that work well at the sub-function level, let alone in html templates.

There's the option of passing an anonymous delegate into a function (which then executes the lambda and disposes of the resource), but that's ugly:

Using.Transaction(new Resource(), ()=>{
Foo();
Bar();
});
And it has some limitations:

The compiler won't enforce that the resource is a previously undeclared resource like using blocks do.
You can't exit the lambda unconventionally like you can a using block (via return, break, continue, yield, goto)
(though the yield case is a known language bug and the other non-return cases are highly distasteful)
You can't access ref/out params from the lambda.
You can't use unsafe code in the lambda.
You can't "chain" the using blocks nicely.
Most of these can be circumvented by using named methods rather than anonymous, but that leads to its own problems.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote