7

I am still fairly new to C# and I have a question regarding attributes. Is it possible to write a custom attribute which generates additional code at compile time. For example:

[Forever]
public void MyMethod()
{
    // Code
}

Turns into:

public void MyMethod()
{
    while (true)
    {
        // Code
    }
}
Dave
  • 7,283
  • 12
  • 55
  • 101
  • Surely you don't want to generate infinite loops. What is your vision? What is your big idea that you want to accomplish using code generation via attributes? – Rick Sladkey May 20 '11 at 00:36
  • 3
    This was just an example, I wanted to know if it was possible. But in general, there are uses for infinite loops. For instance you have a thread that does something over and over again. You put in Thread.Sleep and an infinite loop and done. – Dave May 20 '11 at 00:49
  • Just an example of what? Why would you not just write the loop instead? What is your plan? We can't help you if you don't have a plan. – Rick Sladkey May 20 '11 at 00:56
  • 5
    A) From my point of view it makes code more readable because you don't need to put another layer of indentation. B) Why does it matter what my plan is, I just wanted to know if it was possible. A simple yes or no will suffice. – Dave May 20 '11 at 01:04
  • 1
    I'm trying to help you. Don't freak out. Even if this **isn't** possible, if you're trying to do something else, **that** might be possible. That's why it matters. If you don't want help, I'll stop trying. – Rick Sladkey May 20 '11 at 01:09
  • no no, don't worry about it. The example above is pretty specific to what what I wanted to do. I just wanted to know the extend of attributes and whether they could actually insert code. As the answer stated, PostSharp does a pretty good job of that. C# has all these convenience functions and its tough to judge from the documentation how good they are or if there is something better that I could use. Thanks though. – Dave May 20 '11 at 01:29

2 Answers2

7

Out of the box, no, this isn't something that can be done. Using PostSharp though, this can be achieved:

http://www.sharpcrafters.com/aop.net/compiletime-weaving

BFree
  • 102,548
  • 21
  • 159
  • 201
3

Afterthought works similar to PostSharp by performing compile-time modifications to your assemblies. In the case of Afterthought you can choose how to identify the changes to make, either by looking for attributes you have defined, looking for common patterns, or simply establishing conventions.

For example, I am working on an example using Afterthought to automatically implement Entity Framework interfaces at compile-time for types exposed by a DbContext in a compiled assembly. In this case I am simply looking for any type that is a subclass of DbContext and then looking at the properties on this type to determine which POCO types to modify to work with Entity Framework.

However, compile-time manipulation of assemblies like this, while powerful, is still for me a choice of last resort. It is not natively supported by the .NET framework and Microsoft tools. Though I wrote Afterthought to support complex cases where this level of indirection was required, I prefer to use standard object-oriented patterns and intrinsic C# language features like delegates as much as possible. Ultimately, introducing custom attributes that inject code introduces a domain specific language into your solution, which will be one or thing to learn/understand for someone reviewing your code, like when answering an SO question ;-)

Jamie Thomas
  • 1,513
  • 1
  • 10
  • 16