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
}
}
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
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 ;-)
Related
I would like to create an C# attribute that accepts a Type parameter.
[MyAttribute(typeof(FooBar))]
public class MyClass
{
Adding this attribute to a class should, among other things, tell Visual Studio implicitly that this class has a member variable of that type, with a name derived from the type.
For example, adding the attribute with the parameter typeof(FooBar) should implicitly create the member variable private FooBar _foobar;.
I would like to be able to access that member via autocomplection in the IDE, so doing this at runtime would be too late.
Is this possible at all? How could I achieve this?
Not without something that rewrites the IL after the compiler has done its thing.
Except for a short list of attributes built into .NET and specifically handled by the compiler, attributes doesn't impact code at all, they're just metadata stored in the final assembly.
One way would be to use something like Postsharp which does the very thing I describe above.
Basically, Postsharp and similar systems takes the final assembly produced by the .NET compiler apart, reads the metadata (attributes and other things) then rebuilds the assembly from the ground up, injecting more code depending on those attributes.
However, with stock .NET and C#, no, this is not possible.
As #MarcinJuraszek comments, this may be possible with Roslyn, the new compiler platform that Microsoft is going to launch. I have little experience with this so my answer is related to current stable releases, which includes .NET 4.5 and C# 5.0.
Microsoft.CSharp is required to use dynamic feature.
I understand there are binders, evaluators and helpers in the assembly.
But why it has to be language-specific?
Why Microsoft.CSharp and not Microsoft.Dynamic or System.Dynamic?
Please, explain.
Let's say we have d.x where d is dynamic.
C# compiler
1. applies C# language rules
2. gets "property or field access"
3. emits (figurally) Binder.GetPropertyOrField(d, "x")
Now, being asked to reference Microsoft.CSharp may make one think that language-agnostic binder can't handle this case, and C#-only something got its way through compilation and requires special library.
Compiler had a bad day?
To your first question, it is language-specific because it needs to be.
In C# you call a method with too many arguments and you get an error. In Javascript, the extra arguments are simply ignored. In C# you access a member that doesn't exist and get an error, while in Javascript you get undefined. Even if you discovered all these varying feature sets and put it all into System.Core, the next language fad of the month is sure to have some super neat feature that it wouldn't support. It's better to be flexible.
There is common code in .NET core, under the System.Dynamic and System.Runtime.CompilerServices namespaces. It just can't all be common.
And as for your second question, the need for the "special C# library" could of course be removed by transforming these language-specific behaviors inline, but why? That will needlessly bloat your IL code size. It is the same reasoning for you not writing your own Int32.Parse every time you need to read in a number.
One reason I can think of - Visual Basic.NET has had late binding in it from day one, primarily oriented around how it interoperates with COM IDispatch interfaces - so if they wanted a language agnostic binder, they'd have had to adopt the Visual Basic rules - which includes that member lookup only works with Public members.
Apparently, the C# designers didn't want to be so strict. You can call this class' DoStuff method from C# via a dynamic reference:
public class Class1
{
internal void DoStuff()
{
Console.WriteLine("Hello");
}
}
Whereas attempting to call the same via Visual Basic's Object results in a MissingMemberException at runtime.
So because the C# designers weren't the first to arrive at the late-binding party, they could either follow Visual Basic's lead or they could say "each language will have its own rules" - they went with the latter.
As shown here, attribute constructors are not called until you reflect to get the attribute values. However, as you may also know, you can only pass compile-time constant values to attribute constructors. Why is this? I think many people would much prefer to do something like this:
[MyAttribute(new MyClass(foo, bar, baz, jQuery)]
than passing a string (causing stringly typed code too!) with those values, turned into strings, and then relying on Regex to try and get the value instead of just using the actual value, and instead of using compile-time warnings/errors depending on exceptions that might be thrown somewhere that has nothing to do with the class except that a method that it called uses some attributes that were typed wrong.
What limitation caused this?
Attributes are part of metadata. You need to be able to reflect on metadata in an assembly without running code in that assembly.
Imagine for example that you are writing a compiler that needs to read attributes from an assembly in order to compile some source code. Do you really want the code in the referenced assembly to be loaded and executed? Do you want to put a requirement on compiler writers that they write compilers that can run arbitrary code in referenced assemblies during the compilation? Code that might crash, or go into infinite loops, or contact databases that the developer doesn't have permission to talk to? The number of awful scenarios is huge and we eliminate all of them by requiring that attributes be dead simple.
The issue is with the constructor arguments. They need to come from somewhere, they are not supplied by code that consumes the attribute. They must be supplied by the Reflection plumbing when it creates the attribute object by calling its constructor. For which it needs the constructor argument values.
This starts at compile time with the compiler parsing the attribute and recording the constructor arguments. It stores those argument values in the assembly metadata in a binary format. At issue then is that the runtime needs a highly standardized way to deserialize those values, one that preferably doesn't depend on any of the .NET classes that you'd normally use the de/serialize data. Because there's no guarantee that such classes are actually available at runtime, they won't be in a very trimmed version of .NET like the Micro Framework.
Even something as common as binary serialization with the BinaryFormatter class is troublesome, note how it requires the [Serializable] attribute on the class to allow it to do its job. Versioning would also be an enormous problem, clearly such a serializer class could never change for the risk of breaking attributes in old assemblies.
This is a rock and a hard place, solved by the CLS designers by heavily restricting the allowed types for an attribute constructor. They didn't leave much, just the simple values types, string, a simple one-dimensional array of them and Type. Never a problem deserializing them since their binary representation is simple and unambiguous. Quite a restriction but attributes can still be pretty expressive. The ultimate fallback is to use a string and decode that string in the constructor at runtime. Creating an object of MyClass isn't an issue, you can do so in the attribute constructor. You'll have to encode the arguments that this constructor needs however as properties of the attribute.
The probably most correct answer as to why you can only use constants for attributes is because the C#/BCL design team did not judge supporting anything else important enough to be added (i.e. not worth the effort).
When you build, the C# compiler will instantiate the attributes you have placed in your code and serialize them, so that they can be stored in the generated assembly. It was probably more important to ensure that attributes can be retrieved quickly and reliably than it was to support more complex scenarios.
Also, code that fails because some attribute property value is wrong is much easier to debug than some framework-internal deserialization error. Consider what would happen if the class definition for MyClass was defined in an external assembly - you compile and embed one version, then update the class definition for MyClass and run your application: boom!
On the other hand, it's seriously frustrating that DateTime instances are not constants.
What limitation caused this?
The reason it isn't possible to do what you describe is probably not caused by any limitation, but it's purely a language design decision. Basically, when designing the language they said "this should be possible but not this". If they really wanted this to be possible, the "limitations" would have been dealt with and this would be possible. I don't know the specific reasoning behind this decision though.
/.../ passing a string (causing stringly typed code too!) with those values, turned into strings, and then relying on Regex to try and get the value instead of just using the actual value /.../
I have been in similar situations. I sometimes wanted to use attributes with lambda expressions to implement something in a functional way. But after all, c# is not a functional language, and if I wrote the code in a non-functional way I haven't had the need for such attributes.
In short, I think like this: If I want to develop this in a functional way, I should use a functional language like f#. Now I use c# and I do it in a non-functional way, and then I don't need such attributes.
Perhaps you should simply reconsider your design and not use the attributes like you currently do.
UPDATE 1:
I claimed c# is not a functional language, but that is a subjective view and there is no rigourous definition of "Functional Language". I agree with the Adam Wright, "/.../ As such, I wouldn't class C# as functional in general discussion - it is, at best, multi-paradigm, with some functional flavour." at Why is C# a functional programmming language?
UPDATE 2:
I found this post by Jon Skeet: https://stackoverflow.com/a/294259/1105687 It regards not allowing generic attribute types, but the reasoning could be similar in this case:
Answer from Eric Lippert (paraphrased): no particular reason, except
to avoid complexity in both the language and compiler for a use case
which doesn't add much value.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# wrap method via attributes
I'd like to achieve such functionality:
[Atomic]
public void Foo()
{
/* foo logic */
}
Where [Atomic] attribute is an attribute, which wraps function logic within a transaction scope:
using(var scope = new TransactionScope())
{
/* foo logic */
scope.Complete();
}
How to write such an attribute?
I've asked before basically the same question, I know this can be done using AOP, but I didn't mention I'm searching for some simplest proof of concept implementation or helpful articles which can help me to write this using pure .NET Framework (I suppose using RealProxy and MarshalByRefObject types, about which I've read browsing related questions).
I need to solve exactly this shown example. It seems like a basic thing so I want to learn how to do it starting from scratch. It doesn't need to be safe and flexible for now.
It seems like a basic thing...
It's one of the (many) things which are simple to understand the concept, but not at all simple to implement.
As per Oded's answer, Attributes in .NET don't do anything. They only exist so that other code (or developers) can look at them later on. Think of it as a fancy comment.
With that in mind, you can write your attribute like this
public class AtomicAttribute : Attribute { }
Now the hard part, you have to write some code to scan for that attribute, and change the behaviour of the code.
Given that C# is a compiled language, and given the rules of the .NET CLR there are theoretically 3 ways to do this
Hook into the C# compiler, and make it output different code when it sees that attribute.
This seems like it would be nice, but it is simply not possible
right now. Perhaps the
Roslyn
project might allow this in future, but for now, you can't do it.
Write something which will scan the .NET assembly after the C# compiler has converted it to MSIL, and change the MSIL.
This is basically what PostSharp does. Scanning and rewriting MSIL is hard. There are libraries such as Mono.Cecil which can help, but it's still a hugely difficult problem. It may also interfere with the debugger, etc.
Use the .NET Profiling API's to monitor the program while it is running, and every time you see a function call with that attribute, redirect it to some other wrapper function.
This is perhaps the simplest option (although it's still very difficult), but the drawback is that your program now must be run under the profiler. This may be fine on your development PC, but it will cause a huge problem if you try deploy it. Also, there is likely to be a large performance hit using this approach.
In my opinion, your best bet is to create a wrapper function which sets up the transaction, and then pass it a lambda which does the actual work. Like this:
public static class Ext
{
public static void Atomic(Action action)
{
using(var scope = new TransactionScope())
{
action();
scope.Commit();
}
}
}
.....
using static Ext; // as of VS2015
public void Foo()
{
Atomic(() => {
// foo logic
}
}
The fancy computer science term for this is Higher order programming
Attributes are meta data - that's all they are.
There are many tools that can take advantage of such metadata, but such tooling needs to be aware of the attribute.
AOP tools like PostSharp read such metadata in order to know what and where to weave aspects into code.
In short - just writing an AtomicAttribute will give you nothing - you will need to pass the compiled assembly through a tool that knows about this attribute and do "something" to it in order to achieve AOP.
It is not a basic thing at all. No extra code is run just because a method has an attribute, so there is nowhere to put your TransactionScope code.
What you would need to do is at application start-up use reflection to iterate over every method on every class in your assembly and find the methods that are marked with AtomicAttribute, then write a custom proxy around that object. Then somehow get everything else to call your proxy instead of the real implementation, perhaps using a dependency injection framework.
Most AOP frameworks do this at build time. PostSharp for example runs after VisualStudio builds your assembly. It scans your assembly and rewrites the IL code to include the proxies and AOP interceptors. This way the assembly is all set to go when it is run, but the IL has changed from what you originally wrote.
Maybe resolve all objects using IoC container?
You could configure interceptors for your types and in them check if called method is decorated with that attribute. You could cache that information so that you don't have to use reflection on every method call.
So when you do this:
var something = IoC.Resolve<ISomething>();
something is not object you have implemented but proxy. In that proxy you can do whatever you want before and after the method call.
Is there a standard framework (maybe part of Enterprise Library... or .NET itself) that allows you to do common parameter validation in method attributes?
The Microsoft Enterprise Library has the Microsoft.Practices.EnterpriseLibrary.Validation library/namespace which allows validation using attributes.
Microsoft Code Contracts, which are part of .NET Framework since 4.0 CTP and are available for earlier .NET Framework versions as a stand-alone package, allow to specify coding assumptions. This includes specifying pre-conditions which can verify parameters.
An example use for parameter checking would be (copied from Code Contracts documentation):
public Rational(int numerator, int denominator)
{
Contract.Requires(denominator ! = 0);
this.numerator = numerator;
this.denominator = denominator;
}
The benefit of using Code Contracts is that it is a library which will be part of future .NET Framework releases, so sooner or later you will have one dependency less in your application.
EDIT: Just noticed that your specifically asking for a library that uses Attributes for argument checking... that Code Contracts does not. The reason why Code Contracts does not use attributes is listed in their FAQ:
The advantage of using custom attributes is that they do not impact the code at all. However, the benefits of using method calls far outweigh the seemingly natural first choice of attributes:
Runtime support: Without depending on a binary rewriter, contracts expressed with attributes cannot be enforced at runtime. This means that if there are preconditions (or other contracts) that you want enforced at runtime, you need to either duplicate the contracts in the code or else include a binary rewriter in your build process. Contract.RequiresAlways serves both as a declarative contract and as a runtime-checked validation.
Need for parsing: Since the values that can be used with custom attributes are limited, conditions end up being encoded as strings. This requires defining a new language that is appropriate for all source languages, requires the strings to be parsed, duplicating all of the functionality the compiler already possesses.
Lack of IDE support: Expressed as strings, there is no support for Intellisense, type checking, or refactoring, all of which are available for authoring contracts as code.
While Microsoft Code Contracts are out for a while, they are still hosted in MS Research and you cannot use configuration (app.config/database etc.) to switch on/off or even change rules. My library Bouncer does provide declarive rule definition: attributes in source code or app.config entries for rules at the entity class/property level. The library is opensource under LGPL (you can freely use it in commercial products). If you configure the rules via app.config you can adjust the rule settings without the need of a recompile.
Dynamic Data for ASP.NET (and ASP.NET MVC) lets you do validation for model properties using attributes.
You could also use postsharp and implement your own attributes for validation.
Here is an example using PostSharp
http://dpatrickcaldwell.blogspot.com/2009/03/validate-parameters-using-attributes.html