[property: Obsolete]
static int X
{
get { return 42; }
}
In the code above, what purpose does the word "property" serve? The code seems to work the same way if I replace [property: Obsolete] with [Obsolete]. And although "property" is coloured blue in Visual Studio, it does not appear in the list of C# keywords:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
The Attribute specification defines this as an attribute target.
Certain contexts permit the specification of an attribute on more than
one target. A program can explicitly specify the target by including
an attribute_target_specifier. When an attribute is placed at the
global level, a global_attribute_target_specifier is required. In all
other locations, a reasonable default is applied, but an
attribute_target_specifier can be used to affirm or override the
default in certain ambiguous cases (or to just affirm the default in
non-ambiguous cases).
It also states that in many cases, like the one you mention, it is permitted but not necessary.
In other contexts, inclusion of an attribute_target_specifier is
permitted but unnecessary. For instance, a class declaration may
either include or omit the specifier type.
This is an attribute target specification.
In your code the use of it is not really necessary, since there is just one allowed target for that attribute at that place. The Obsolete attribute can be placed on a type, method or a property, but if placed on a property, only the property target specifier is allowed (and used implicitly).
The most practical use for this is the assembly target specifier, where you can set assembly configuration through attributes:
[assembly: AssemblyProduct("Foo bar")]
You can set the allowed targets on your custom attributes using AttributeUsage.
Related
As is well known, in C# one can specify the target of a custom attribute specification, as in the example
[method: SomeDecoration]
[return: SomeOtherMark]
int MyMethod();
where the "targets" method: and return: help specify what element in the code the attribute belongs to.
According to the C# Language Specification, the following attribute targets exist:
Global ones:
assembly
module
Others:
field
event
method
param
property
return
type
Some of them, like field, are always redundant, since it is always clear what the attribute "sits" on without specifying them.
However there does exist (at least in the implementation and version of Visual C# I have here) an additional attribute target, namely:
typevar
which is allowed for example in the code
class MyGenericCollection<[typevar: HereYouSee] TItem> // legal
{
}
The attribute target typevar, just like field and others, is never required.
My question: Does anyone know the historic reason why typevar: is not mentioned in the specification or documentation? Was this simply forgotten when the 2.0 version of the C# Language Specification was written? Or if it was not an oversight, why is it implemented at all?
Actually, typevar attribute target is documented, but it seems that only in the standardized C# 2.0 Language Specification:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf#page=399
Neither C# 3.0, nor 5.0 Language Specification mentions typevar. (I didn't find C# 4.0 spec.)
So answering your second question, no, it wasn't forgotten in C# 2.0, but it is forgotten since then :) I think this must be an oversight, since the typevar attribute target is still (C# 5.0) valid.
I used a decompiler to extract all the code from a DLL (SharpSVN -- cannot get my hands on the source code) and I want to modify an enum to give it a DisplayName.
public enum SvnStatus
{
Zero,
None,
[DisplayName("Not Versioned")]
NotVersioned,
//other one-word values that don't need a display name
}
But this gives me the following error:
Attribute 'System.ComponentModel.DisplayNameAttribute' is not valid on this declaration type. It is valid on 'Class, Method, Property, Event' declarations only.
Googled around and found a number of threads where people seem to do this no problem with their enums. Am I missing something? I can't Resolve the error in Visual Studio, the option doesn't even show up (but that might be because I just installed Resharper and am not familiar with it yet?)
Edit: Just found DevExpress has a CustomColumnDisplayText event where I can change the value as desired, so I'm going to go with that instead, since the data is only being displayed in a GridControl.
The reason is given in the error you're getting.
The System.ComponentModel.DisplayNameAttribute has been attributed with a System.AttributeUsageAttribute which constricts the usage to only be applied to classes, methods, properties, or events. Enums are excluded. It looks like this:
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Method|AttributeTargets.Property|AttributeTargets.Event)]
Perhaps you can write your own attribute instead?
Is it possible to add an exception to Resharper naming conventions for a specific word? In particular, I'd like to be able to make an enum value "iPhone", even though I generally prefer PascalCase for enum values.
I checked out Resharper's naming style documentation, but didn't see any way to add a custom exception. I also tried using the custom abbreviations list, but that only works for all caps.
You can't add an exception for specific word, but there's some kind of workaround.
With ReSharper you can add more than one naming rules for a member. You can add new rule for "enum members" settings and set its name prefix to "iPhone". With this setting you'll be able to define "iPhone" enum value. Notice that with this setting you'll also be able to define "iPhoneWithReallyCoolFeature" enum value, because it doesn't violate this rule.
Screenshot for settings:
Update:
If you don't mind of polluting your code, you can add
// ReSharper disable once InconsistentNaming
just before your "iPhone" enum member.
Just to confirm there isn't a way to avoid hard-coded values in c# attributes right?
[SomeAttribute(3+1)]
public void Foo(string s)
or access class members or do anything not precompiled?
I now explore the great example of retry mechanism in postsharp - and would like to see if I can configure the number of retries from outside the system
Attribute constructor arguments and property values are baked into the compiled code. They can't be determined at execution time.
Of course, if you have attribute which is willing to play ball, you could give it (say) a type and the name of a property, and ask it to fetch that property value at execution time. (That's what NUnit does for [TestCaseSource], for example.) But you can't do this with an attribute which doesn't know to do so.
I am curious to know why when we are doing P/invoke
the dllimport call is in a "["
and not just a class or a function
e.g.:
[DllImport("something.dll",....)]
rather than
DllImport("something.dll,....)
or even
DllImport.import(something.dll...)
I do not want to rewrite it, my questions is what does "[" represent or mean ? what is it called in this instance ? Why is it used ?
In this context, it signifies an "attribute"; DllImportAttribute (MSDN). Simply : it is a syntax already in the language for adding metadata to the code.
The language allows you to define your own attributes, or any from libraries. Attributes can be used on assemblies, types, methods, properties, fields, events, parameters, etc - or restricted to a small subset of that. DllImportAttribute is limited to methods, for example. Most only have meaning when inspected with reflection at runtime, but some re handled directly by the compiler.
DllImport is not a method. It is an attribute. The brackets are just the syntax for applying attributes.
The syntax is specified in appendix B of the C# specification, section B.2.13, Attributes.