Ann said:
I keep coming accross C# code that has sections of code like this:
[System.Diagnostics.ConditionalAttribute]
Just to add to what the others have said.
Metadata is information that describes .NET types. There is runtime
metadata that the compiler *must* generate, and there is custom metadata
that the developer can add. Now it gets complicated and Microsoft's
documentation does not help. .NET languages add metadata through
attributes, however, both custom *and* runtime metadata can be added
using the same mechanism.
For example, the attribute you give, [Conditional] (you can omit the
Attribute suffix) is a *custom* attribute, it tells the compiler to add
custom metadata to the assembly. This custom metadata is read by a
compiler when it compiles code that will use the library, and it
indicates that a call to the code marked with this attribute can only be
made if a particular compiler symbol is defined. The [Conditional]
custom metadata is added to the library that has this attribute, but the
runtime will ignore this metadata. These are known as _custom
attributes_. You can use Type.GetCustomAttributes (or
Attribute.GetCustomAttribute) to get access to this metadata.
Another attribute, [Serializable] does not add custom metadata, instead
it is a message to the compiler to change the runtime metadata that it
will generate (in this case, set the runtime metadata on a class to show
that it is serializable). Another example is [AssemblyVersion] that
tells the compiler to set the assembly metadata to the specified
version. There is no custom metadata added to the assembly, so you
*cannot* access this information through Type.GetCustomAttributes.
(There are other reflection methods/properties to get this information.)
These are known as _pseudo custom attributes_.
In general, the runtime will ignore the metadata from custom attributes,
but it will act upon the metadata from pseudo custom attributes.
However, there are some custom attributes that the runtime will pay
attention to. An example is [OneWay] which indicates that a method
should be called in a fire-and-forget fashion (that is, it does not
return a value) this adds custom metadata to the method, but the runtime
will specifically look for this custom metadata and act upon it. You can
read this custom metadata using Type.GetCustomAttributes. These
attributes are called _distinguished custom attributes_.
So there are three types of 'custom attributes', but what is so special
about serialization? I don't know. I don't know why the serializable
runtime metadata has to be specified with a pseudo custom attribute and
not with a keyword. For example, the visibility of a type (public,
private, internal, yet another piece of metadata) is not specified with
a pseudo custom attribute it is specified with a keyword.
This is the accepted syntax:
[Serializable]
public class MyData
{
}
However, since public tells the compiler to generate metadata the C#
language designers could have been more consistent and used the
following (this is not code that will compile with the current
compilers):
[Serializable]
[Public]
class MyData
{
}
or (more readable)
[Serializable, Public]
class MyData
{
}
IMO the C# language designers have been inconsitent. Their use of custom
attributes is a mess. But then again, they never listen to my
opinions...
As you can see the three types of attributes are very different in how
they are implemented and what code uses them. Sadly the .NET
documentation does not make this obvious.
Richard