We're writing a .NET 3.5 application, which uses Xml serialization of various objects.
We are basically creating an xml document from an object, and i'd like to be able to use this attribute (DefaultParameterValue) which is what .NET 4.0 is using to implement optional arguments.
I'd like the Xml generated document to contain the default values for the parameters that have this attribute.
Is it possible?
XmlSerializer operates at the (public) field/property level. In doing so, one of the things it looks at is the similar [DefaultValue(...)]. It does not look at methods at all, except for a few assistance patterns like ShouldSerialize*(). As such, there would seen to be no crossover at all with parameters, ad no need to look at [DefaultParameterValue(...)].
This is not how attributes work. The ones that xml de/serializers recognize are well documented, the list is not extensible. Adding more requires changing code. Code that you cannot change, it is locked up inside a framework assembly.
Implement the equivalent by assigning the default value you want in the class constructor.
Related
I am using ProtoBuf-Net to send decorated objects over TCP - and it works like a charm.
But I want to serialize the same objects also into a file, with a different decoration. That means, I want to have other properties saved here.
I don't think manipulating attributes is possible at runtime, so what other options do I have?
Thanks in advance!
(I'm very sorry if this was asked before, but I was unable to find anything with the search term 'different')
See the documentation:
Alternative to attributes
In v2, everything that can be done with attributes can also be configured at runtime via >RuntimeTypeModel. The Serializer.* methods are basically just shortcuts to >RuntimeTypeModel.Default., so to manipulate the behavior of Serializer., you must >configure RuntimeTypeModel.Default.
or this question:
Protobuf-net serialization without annotation
Basically, instead of annotations, you can configure everything yourself through the RuntimeTypeModel
Syntactically I understand how C# attributes are applied (i.e. denoted in square brackets []). But it is not obvious what effects adding attributes actually has.
For instance:
Are attributes meant to be a type of commenting?
How are these attributes handled by the C# compiler?
Will these C# attributes change the C# program execution in any way?
Attributes are not comments; they are classes that get added to the metadata of "things" in C#. By "things" I mean classes, properties, methods, etc.
An attribute absolutely can change the execution of a program... if something uses Reflection to read and act on the attributes. For example; the [DataMember] attribute will allow a DataContractSerializer to include that member in a serialized object. The [Export] attribute will be picked up by MEF code as a plugin.
There are many other examples and you can also create your own.
For far more information about attributes see: Attributes in C#
Attributes are a powerful construct that can indirectly affect the code execution. You can inspect self or other classes using Reflection and change behaviour based on the presence of certain attributes.
Take a look at the c# programming guide: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/
Since Attributes are really just Metadata attached to assemblies, does that mean that Attribute Objects are only created on request (such as when you call GetCustomAttributes)?
Or are they created on creation of the object?
Or, a combination of the first 2, created when the object is created due to attribute scanning by the CLR?
From CLR via C#, third edition:
If you want to construct an attribute object, you must call either GetCustomAttributes or
GetCustomAttribute. Every time one of these methods is called, it constructs new instances
of the specified attribute type and sets each of the instance’s fields and properties based on the values specified in the source code. These methods return references to fully constructed instances of the applied attribute classes.
So yes, they are only created on request.
They are created on request.
For example, if you add some .NET 3.0 attributes to a .NET 2.0 Assembly (e.g. WCF DataContractAttribute), you'll still be able to use the .NET 2.0 Assembly on a machine that doesn't have .NET 3.0 installed, provided you don't have any code that attempts to access the attributes.
It is not quite that clean, attributes also affect code generation. Some attributes are interpreted by the compiler, [DllImport] for example. Some are discovered by the jitter, [MethodImpl] for example. This is infinitely extended to other tools and classes in the framework that were written to take advantage of attributes.
But these tools are just doing what you need to do if you want to find your own attributes, calling GetCustomAttributes() is required. That kind of code is never associated with an instance of the object, attributes apply to types.
Could anyone explain the benefits (or reasons) to use custom attributes in your code. Of course I use (and understand the purpose of) defined attributes in certain scenarios (WCF, Serialization etc.), but I cannot imagine any algorithms where I would need to create and use my own custom attributes. Could someone provide a real-world case where usages of custom defined attributes bring something to a project.
The same reason as for WCF etc, but something that's specific to your project - you want to add some metadata to some members (types, fields, methods, whatever) to specify something about the mechanism involved, and it's not something which is covered by existing attributes.
For example, NUnit wanted to add their own indication that a particular type contained unit tests - there was no such existing attribute, so they created TestFixtureAttribute.
It's a relatively rare event, sure - but it can happen.
If you want to write your own system like WCF, Serialization, etc...
If you write code that iterates over types or members and does things with them, you will frequently want to use your own custom attributes to mark some members as being different or special.
I regularly use custom .Net attributes to support tooling in my infrastructure. One example was from very early in the .Net days (C# 1.0 to be exact). I was working on a research project which had a native C++ front and a brand new C# back end written by yours truly.
The front and back end shared a very similar object model which was evolving very rapidly. Not wanting to have to hand code both a C++ front end model, C++ serialization mechanism and a C# serialization mechanism I chose instead to attribute my C# types with custom attributes. They told me the parts of the model which were shared between the front and back end.
Once those attributes were in place I wrote a quick and dirty tool which
Parsed out the attributes to construct the core shared model
Generated the C# serialization code
Generated the C++ code
Generated the C++ serialization code
This made it dirt simple to keep my model up to date between my 2 projects. Just change the C# code, compile and re-run my tool.
I have used annotations in a custom AOP (Aspect-Oriented Programming) system I developed a while back. Attributes are also very useful for controlling orthogonal concerns like code generation.
Custom validation is a very good use case and can be seen from these links:
http://odetocode.com/blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx
How to create Custom Data Annotation Validators
They can be used for marking tests, as in MBUnit for example. They can also be useful for code that inspects and loads classes (like a Plugin system) to provide meta-information.
They are really useful in building object mappers / ORM tools as well. If you ever decide to roll your own mapping system they are almost "required" to get all the functionality one would need. It's used more for making methods / classes more generic and using reflection to determine how to handle objects / select objects /etc...
To give you a specific case where I've used them. I once had to interact with a Mainframe screenscraper. I created a custom attribute to annotate which fields I wanted to send from my classes to the Mainframe, names that fell outside of conventions, special rules to deal with formatting and collections. I then had a class which was able to reflect over instances and realise which subset of fields were needed to interact with the mainframe screen scraper appropriately.
I'm writing some library code, and classes that use that code are required to have two attributes specified (one custom attribute and one from .NET).
It's a bit of a hassle to document this requirement and copy-and-paste both of those attributes onto every class that uses my library, so I thought it might be better to have my custom attribute just imply the presence of the other. That other attribute from the .NET framework is sealed, though, so I can't just inherit it...
So is there any way to do this? Can I maybe add the .NET attribute at runtime?
Thanks.
Whilst you can use inheritance in attributes it is recommended you don't.
Since this is only a performance rule you will not violate correctness but it can be a source of some confusion and you must spend a great deal of effort to ensure you do not violate the semantics of the base attribute. You may cause issues if you attempt to expand the possible locations for the attribute with the AttributeUsage flags. The rules for the attribute in question are quite complex.
A method can have either of the two attributes applied, but not both. Any operation that has neither applied uses the attribute applied to the containing class. If the containing class does not have either attribute applied, the DataContractSerializer is used.
Give this making it sealed sounds like a sensible plan on their part. This API is not designed with this sort of extension in mind.
There is no way (short of AOP style 'code injection') to add attributes to existing classes at runtime.
I do not believe there is a way to imply secondary attributes or to add attributes at runtime. However, you could use a custom code template to add the attributes to every class as you add them. And/or for classes that are already developed, I suspect you could write a macro that goes through each file and adds the attributes to the classes, however I have not done this in the past, so I'm not sure what it would entail, I know making a code template to add to attributes to a class declaration is relatively simple. But this only works for class you're adding from the point of template addition on. If you need to do cleanup to old classes as well, I would look into macros if you have a lot of files/classes this needs to be done for. Or do it manually if there are not too many.