Can I implicitly create member variables via attributes? - c#

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.

Related

Why does "dynamic" require language-specific runtime components?

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.

Reverse of Deprecated / Obsolete

I have a functionality in my code, but it will be available from next version. Is there any tags to notify that it is not in use, but will be available in future. I just have one way ie, [Obsolete] with custom message. Expecting other than this.Thanks in advance.
If it is not available in the current version, don't make it part of the public API. Don't expose stuff that shouldn't be used by consumers of your library.
And even when it's not a library, don't add code that you don't yet need. That violates the YAGNI principle. Add the code only when it is actually needed.
You can create throw a CustomError message from that method saying "This method is not available for the current version. It is for future" something like that.
Or else you can make the method as Obselete and specify the reason in the message.
[Obsolete("I have written this method for future use. Do not use it in the current version.")]
Judging from your question, I assume you want to generate a compiler warning when someone attempts to call this method, stating that it has not yet been implemented.
ObsoleteAttribute is hard coded into the C# compiler as something that should generate a warning message. Therefore there is no way to mark a method as 'to be implemented in the future' without modifying the compiler itself.
From the C# Spec:
The attribute Obsolete is used to mark types and members of types that
should no longer be used.
If a program uses a type or member that is decorated with the Obsolete attribute, the compiler issues a warning or an error.
Specifically, the compiler issues a warning if no error parameter is
provided, or if the error parameter is provided and has the value
false. The compiler issues an error if the error parameter is
specified and has the value true.
I suggest to not expose methods that are not yet implemented, since it makes no sense to use them. If this is part of a team development effort, specifying API contracts before developing specific modules, you should consider throwing a NotImplementedException or provide a dummy implementation.
Reviving this question as there is now a real solution thanks to Roslyn: Code analyzers.
Just add this Nuget package to your project and you'll be able to create attributes that will be picked up by the compiler!
The GitHub repo readme has the instructions, and it's really simple.

Generating additional code through a custom attribute

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 ;-)

Is .Net attribute feature used at compile-time or run-time or both?

In .Net, is the attribute feature used at compile-time or run-time or both? Can you give me some examples?
Most are used at runtime only. A very limited number are used by the compiler, including:
[Conditional(...)] - omit method calls per build symbols
[Obsolete(...)] - emit a warning/error as build output
[Serializable] - gets written as a CLI flag
[Extension] - used for extension methods
[AttributeUsage] - affects how attributes are applied
-
There are a range of things like [AssemblyVersion], [AssemblyFileVersion] etc that are used by the compiler when creating the assembly file, and things like [InternalsVisibleTo] which affect accessibility.
Additionally, tools like PostSharp do extra post-compile steps based on attributes.
There are some other attributes that the compiler may add to generated types/methods (for anon-methods / types, iterator blocks, etc).
Attributes are output as metadata to the assembly at compile time. This meta data is then used at runtime via reflection - for example using GetCustomAttributes().
Some attributes are used by the compiler at compile time, too. For example the compiler looks at the AttributeUsageAttribute to determine if an attribute can be used for a specific object.
Attributes are compiled into the code at compile time, but they are often used at runtime as triggers to do things differently.
The compiler adds what is called metadata to the object that is decorated with an attribute. This metadata, whether created via attributes or otherwise, is all accessible at run-time thru Reflection. Thus, you can decorate with attributes and then read the details when the program is running. However, to say that the metadata is "used" at compile time isn't quite correct, as the compiler doesn't care what metadata there is.

Attributes in C#

I know that C# (and .NET in general) is big on attributes. However, despite the fact I have programmed in C# for many years, I haven't found myself ever using them. Would someone get me started on them, and explain where is the best to use them?
Thanks
From Pro C# 2008 and the .NET 3.5 Platform, Fourth Edition by Andrew Troelsen
Understanding Attributed Programming
One role of a .NET compiler is to generate metadata
descriptions for all defined and referenced types. In addition to this standard metadata contained
within any assembly, the .NET platform provides a way for programmers to embed additional
metadata into an assembly using attributes. In a nutshell, attributes are nothing more than code
annotations that can be applied to a given type (class, interface, structure, etc.), member (property,
method, etc.), assembly, or module.
The idea of annotating code using attributes is not new. COM IDL provided numerous predefined
attributes that allowed developers to describe the types contained within a given COM server.
However, COM attributes were little more than a set of keywords. If a COM developer needed to
create a custom attribute, he or she could do so, but it was referenced in code by a 128-bit number
(GUID), which was cumbersome at best.
Unlike COM IDL attributes (which again were simply keywords), .NET attributes are class types
that extend the abstract System.Attribute base class. As you explore the .NET namespaces, you will
find many predefined attributes that you are able to make use of in your applications. Furthermore,
you are free to build custom attributes to further qualify the behavior of your types by creating a
new type deriving from Attribute.
Understand that when you apply attributes in your code, the embedded metadata is essentially
useless until another piece of software explicitly reflects over the information. If this is not the case,
the blurb of metadata embedded within the assembly is ignored and completely harmless.
Attribute Consumers
As you would guess, the .NET 3.5 Framework SDK ships with numerous utilities that are indeed on
the lookout for various attributes. The C# compiler (csc.exe) itself has been preprogrammed to
discover the presence of various attributes during the compilation cycle. For example, if the C#
compiler encounters the [CLSCompliant] attribute, it will automatically check the attributed item to
ensure it is exposing only CLS-compliant constructs. By way of another example, if the C# compiler
discovers an item attributed with the [Obsolete] attribute, it will display a compiler warning in the
Visual Studio 2008 Error List window.
In addition to development tools, numerous methods in the .NET base class libraries are preprogrammed
to reflect over specific attributes. For example, if you wish to persist the state of an
object to file, all you are required to do is annotate your class with the [Serializable] attribute. If
the Serialize() method of the BinaryFormatter class encounters this attribute, the object is automatically
persisted to file in a compact binary format.
The .NET CLR is also on the prowl for the presence of certain attributes. Perhaps the most
famous .NET attribute is [WebMethod]. If you wish to expose a method via HTTP requests and automatically
encode the method return value as XML, simply apply [WebMethod] to the method and the
CLR handles the details. Beyond web service development, attributes are critical to the operation of
the .NET security system, Windows Communication Foundation, and COM/.NET interoperability
(and so on).
Finally, you are free to build applications that are programmed to reflect over your own custom
attributes as well as any attribute in the .NET base class libraries. By doing so, you are essentially
able to create a set of “keywords” that are understood by a specific set of assemblies.
Applying Attributes in C#
The .NET base class library provides a number of attributes in various
namespaces. Below is a snapshot of some—but by absolutely no means all—predefined
attributes.
A Tiny Sampling of Predefined Attributes
[CLSCompliant]
Enforces the annotated item to conform to the rules of the Common
Language Specification (CLS). Recall that CLS-compliant types are
guaranteed to be used seamlessly across all .NET programming languages.
[DllImport]
Allows .NET code to make calls to any unmanaged C- or C++-based code
library, including the API of the underlying operating system. Do note that
[DllImport] is not used when communicating with COM-based software.
[Obsolete]
Marks a deprecated type or member. If other programmers attempt to use
such an item, they will receive a compiler warning describing the error of
their ways.
[Serializable]
Marks a class or structure as being “serializable,” meaning it is able to persist
its current state into a stream.
[NonSerialized]
Specifies that a given field in a class or structure should not be persisted
during the serialization process.
[WebMethod]
Marks a method as being invokable via HTTP requests and instructs the CLR
to serialize the method return value as XML.
Building Custom Attributes
The first step in building a custom attribute is to create a new class deriving from System.Attribute. Example:
// A custom attribute.
public sealed class VehicleDescriptionAttribute : System.Attribute
{
private string msgData;
public VehicleDescriptionAttribute(string description)
{
msgData = description;
}
public VehicleDescriptionAttribute() { }
public string Description
{
get { return msgData; }
set { msgData = value; }
}
}
As you can see, VehicleDescriptionAttribute maintains a private internal string (msgData)
that can be set using a custom constructor and manipulated using a type property (Description).
Beyond the fact that this class derived from System.Attribute, there is nothing unique to this class
definition.
For security reasons, it is considered a .NET best practice to design all custom attributes as sealed. In
fact, Visual Studio 2008 provides a code snippet named Attribute that will dump out a new System.
Attribute-derived class into your code window.
Attributes get more use in code targeted to other programmers or between distinct parts of a program, rather than code targeted at end users.
For example, you could use attributes to import a dll, indicate how types would interact with visual studio (designer visible, intellisense helps, debugger step-through, etc), how to serialize them, indicate a type is obsolete, describe default values, descriptions, handle COM access, etc.
Those are things that are largely invisible to the end user and that a single programmer could put elsewhere in the source code. But they're useful when only the compiled binary is available and not the source.
I like to use attributes as metadata to my code. We have created some simple attributes that let us tag who wrote what code, when, and why. This lets us have both documented changes in code and in runtime. If there are any exceptions during runtime, we can inspect the callstack, look at any attributes on the methods along the way, and track down the people responsible:
[Author("Erich", "2009/04/06", Comment = "blah blah blah")]
public void MyFunction()
{
...
}
Of course, we could use our source control to look at who checked in what code, but this I've found makes the information more available in the place where you need it. Also, if we ever change source control, that information will not be lost since it is persisted in code.
Attributes are a form of declarative programming, 'similar' to creating your UI in XAML. It 'marks' pieces of code (classes, methods, properties, whatever) with an attribute so that you can later gather all those pieces marked in a specific way and then do something standard with all of them.
Eg. Consider the scenario where you have certain sections of code that you want to run once each time your app starts. In one model of programming (non-attribute) you go to your main method and explicitly call those init methods. With attributes you simply gather all methods which you've marked with your 'init' attribute, and call them via reflection.
The same pattern holds for actions like serialization, persistence and whatnot...
I believe you mean that you do not use (or frequently use) custom defined attributes ?
In my current project, I make heavy use of custom attributes, but, the fact that you need to keep in the back of your mind, is that using attributes should not be a goal on itself.
It is a tool / purpose to get to a given solution.
I sometimes use custom attributes in combination with a weaver like PostSharp, to decorate methods where some weaving should be applied to at compile-time.
In my current project, I also use attributes to decorate certain types with additional info ... But I believe I've posted about this here before:
Cool uses of Attributes or Annotations (CLR or Java)?
I use attributes for the following:
Communicating with a plug-in architecture
Telling another framework what to do with the code (NUnit, for instance)
Adding metadata for use with other code (See PropertyGrid)
Mapping objects to databases (See Castle ActiveRecord)
When writing my own APIs to allow users to communicate metadata
In framework code to tell the debugger to skip over it
Those are off the top of my head. I use them in many other places
Attributes are very good at describing some runtime behaviour of your code that is orthoganal to the code in question. For example, in a class called Customer you would model a customer, right? But you might not want to model or describe the way a Customer object is serialized.
Adding attributes to your Customer class allows you to tell some other part of the runtime how it should deal with your Customer.
MSTest and NUnit makes use of attributes to tell the test framework how it should use classes that define test fixtures.
ASP.NET MVC uses attribute to tell the mvc framework which methods on classes it should treat as controller actions.
So, any place where you have a runtime behaviour that you wish to model attributes can be useful.
Class Attribute definition is available here
ClassInterfaceAttribute : Indicates the type of class interface to be generated for a class exposed to COM, if an interface is generated at all.
ComDefaultInterfaceAttribute : Specifies a default interface to expose to COM. This class cannot be inherited.
ComVisibleAttribute: Controls accessibility of an individual managed type or member, or of all types within an assembly, to COM.

Categories

Resources