I am trying to clean up warnings R# 6.1 is generating for my classes and one of the issues ReSharper is reporting is that I have incorrect capitalization on a variable. For instance I have var RECDLeft = new RECD(); and it recommends that I change it to var recdLeft = new RECD() despite it being an acronymn defined in the list. I have manually added the RECD acronym to the list of acronyms because it wasn't asking me to add it in the quick fix menu. I have noticed that if I call the variable `var aRECDLeft' it recognizes the acronym properly. Is there a reason acronyms are not recognized at the beginning of a variable name? And is there a way to make R# recognize this usage besides moving the acronym to the second word?
Thanks,
Mark Smith
In answer to your first question, I guess R# is trying to conform to Microsoft's C# conventions for acronyms:
Capitalization Rules for Acronyms
Do capitalize both characters of two-character acronyms, except the first word of a camel-cased identifier.
A property named DBRate is an example of a short acronym (DB) used as the first word of a Pascal-cased identifier. A parameter named ioChannel is an example of a short acronym (IO) used as the first word of a camel-cased identifier.
Do capitalize only the first character of acronyms with three or more characters, except the first word of a camel-cased identifier.
A class named XmlWriter is an example of a long acronym used as the first word of a Pascal-cased identifier. A parameter named htmlReader is an example of a long acronym used as the first word of a camel-cased identifier.
Do not capitalize any of the characters of any acronyms, whatever their length, at the beginning of a camel-cased identifier.
A parameter named xmlStream is an example of a long acronym (xml) used as the first word of a camel-cased identifier. A parameter named dbServerName is an example of a short acronym (db) used as the first word of a camel-cased identifier.
As siride correctly points out, this is a special naming case that requires introducing a special naming rule for local variables that would be checked in addition to your default rule. Here's what you should do:
Go to ReSharper > Options > Code Editing > C# > C# Naming Style
Select Local variables, and click Edit.
In the Edit Rule Settings dialog box, what you see by default is one single rule, lowerCamelCase. You could have changed it to another style though.
What you need to do is add another naming rule by clicking Add and set both name prefix (RECD in your case) and style to UpperCamelCase. If you only add the prefix, ReSharper will keep bitching (and giving some funny renaming suggestions) because you also spell "Left" instead of "left".
If you have other similar abbreviations, you should add an additional local var naming rule for each of them (the entire list of known abbreviations is available at C# Naming Style > Advanced settings > Abbreviations as plain text.) This is not very handy to do but it's not that you have a simple naming standard either )
Hope this helps.
I'm guessing the problem is that although the acronym is added, you are still violating the rule that variable names start with lowercase. You'd need to add a special rule for variable names that allows them to begin with that acronym. This is not the same as adding an acronym to the list.
Related
The "#" character is allowed as a prefix to enable keywords to be used as identifiers.
Majority of .net developers know about this.
But what we may not know:
Two identifiers are considered the same if they are identical after the "#" prefix is removed.
So
static void Main(string[] args)
{
int x = 123;
Console.WriteLine(#x);
}
is absolutely valid code and prints 123 to the console.
I'm curious why do we have such rule in the specs, and how this feature may be used in real world situations (it doesn't make sense to prefix identifiers with "#" if they are not keywords, right?).
It is totally logical. # is not part of the name but is a special indicator to not treat what comes after as a keyword but as an identifier.
Eric Lippert has a very good post about it: Verbatim Identifier
I’m occasionally asked why it is that any identifier can be made into
a verbatim identifier. Why not restrict the verbatim identifiers to
the reserved and contextual keywords?
The answer is straightforward. Imagine that we are back in the day
when C# 2.0 just shipped. You have a C# 1.0 program that uses yield
as an identifier, which is entirely reasonable; “yield” is a common
term in many business and scientific applications. Now, C# 2.0 was
carefully designed so that C# 1.0 programs that use yield as an
identifier are still legal C# 2.0 programs; it only has its special
meaning when it appears before return, and that never happened in a C#
1.0 program. But still, you decide that you’re going to mark the usages of yield in your program as verbatim identifiers so that it is
more clear to the future readers of the code that it is being used as
an identifier, not as part of an iterator
Let's consider the example of a program that generates C# code -- for example, something that takes the columns in a database table and creates a comparable C# POCO object, with one property per column.
What if one of the column names matches a C# keyword? The code generator doesn't have to remember which words are keywords or not if all of the property names are prefixed with #.
It's a fail-safe. The extra # characters don't hurt the code at all!!
The other answers are pretty clear about why the behavior exists, but I think it might be worthwhile to look at the rules for which identifiers are treated as equal.
Quoting the specification section 2.4.2:
Two identifiers are considered the same if they are identical after the following transformations are applied, in order:
The prefix "#", if used, is removed
Each unicode-escape-sequence is transformed into it's corresponding Unicode character.
Any formatting-characters are removed.
Following those rules, #x is identical to x.
It provides certainty:
Using #word is future-proof.
No changes are needed if it becomes a keyword later.
Most programmers will not be familiar with every keyword (C# has approx. 100 keywords)
The more recent keywords are "contextual", so sometimes they are not keywords.
In my domain model I have an Event entity. This means that I have to sometimes declare variables as: #event since event is a reserved key word.
I've read on a few stack overflow posts (like What's the use/meaning of the # character in variable names in C#?) that this is not recommended unless you're interacting with other programming languages. My question is why is it not recommended? What is the issue with using #?
I could use an "Occasion" entity instead but that would mean in my UI layer I would have events which maps to occasions?
What you're trying to do is the entire purpose of the # prefix to prevent name clashes.
But this text from MSDN says everything you're asking:
The prefix "#" enables the use of keywords as identifiers, which is
useful when interfacing with other programming languages. The
character # is not actually part of the identifier, so the identifier
might be seen in other languages as a normal identifier, without the
prefix. An identifier with an # prefix is called a verbatim
identifier. Use of the # prefix for identifiers that are not keywords
is permitted, but strongly discouraged as a matter of style.
Source
So it just comes down to style, in your case it's the right solution if you don't want to rename your entity.
FxCop 10 is complaining about the following:
using XYZ.Blah; //CA1709 - "XYZ"
using Xyz.Blah; //No complaint.
using XylophoneSuperDuperLongFullName.Blah; //I don't want to have a long full name for my company name.
The problem is... I want my company name to show up in all UPPERCASE because XYZ is an abbreviation. The long version of the name is much too long to be a useful namespace. Microsoft gets away with this kind of stuff because their acronym is only 2 letters.
using MS.Something; //No Complaint.
using Microsoft.SomethingElse; //No Complaint.
So, I was looking at adding a SuppressMessageAttribute to suppress this warning. But, I'm not sure how to do so properly to only (or where to even stick it) so that it ONLY affects this one instance. I don't want to Suppress anything within that namespace because I want to catch any other mistakes I make. I did look at at the msdn and google searched but I can't find anything that shows how to specifically just target this instance. The closest I found was Scope = "namespace" but I wasn't sure if that means it affects the actual namespace name or if it affects everything WITHIN that namespace.
MSDN - CA1709: Identifiers should be cased correctly:
It is safe to suppress this warning if
you have your own naming conventions,
or if the identifier represents a
proper name, for example, the name of
a company or a technology.
You can also add specific terms,
abbreviations, and acronyms that to a
code analysis custom dictionary. Terms
specified in the custom dictionary
will not cause violations of this
rule. For more information, see How
to: Customize the Code Analysis
Dictionary.
That being said, if you feel justified to suppress the message, it really isn't hard at all. In FxCop 10 right click on any message you want to suppress and go to Copy As>Suppress-Message or Copy As>Module-level Suppress Message.
You should place the SuppressMessageAttributes in the appropriate locations. Attributes that suppress a single location should be placed on that location, for example, above a method, field, property, or class.
In you're instance, there is no specific location to place the attribute (by default it should copy over as [module: SuppressMessage(...)]. This is a good indication that it belongs either at the top of a file if it is a module-level suppression particular to a file (for example, to a resource specific to a file). Or, and more likely, it belongs in a GlobalSuppressions.cs file.
using System.Diagnostics.CodeAnalysis;
[module: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", Justification = "Because I said so!", MessageId = "XYZ", Scope = "namespace", Target = "XYZ.Blah")]
You can also shorten the CheckId property if you want to, but it's good to know what CA1709 means. If you don't feel like it, this also works:
using System.Diagnostics.CodeAnalysis;
[module: SuppressMessage("Microsoft.Naming", "CA1709", Justification = "Because I said so!", MessageId = "XYZ", Scope = "namespace", Target = "XYZ.Blah")]
And lastly... all this will be fruitless unless you include the 'CODE_ANALYSIS' symbol in your build. Go to Properties>Build and add the conditional compilation symbol.
Acryonyms aren't meant to be all upper case in .NET naming conventions. For example HttpResponse etc.
From the capitalization conventions:
Casing of acronyms depends on the length of the acronym. All acronyms are at least two characters long. For the purposes of these guidelines, if an acronym is exactly two characters, it is considered a short acronym. An acronym of three or more characters is a long acronym.
The following guidelines specify the proper casing for short and long acronyms. The identifier casing rules take precedence over acronym casing rules.
Do capitalize both characters of two-character acronyms, except the first word of a camel-cased identifier.
A property named DBRate is an example of a short acronym (DB) used as the first word of a Pascal-cased identifier. A parameter named ioChannel is an example of a short acronym (IO) used as the first word of a camel-cased identifier.
Do capitalize only the first character of acronyms with three or more characters, except the first word of a camel-cased identifier.
A class named XmlWriter is an example of a long acronym used as the first word of a Pascal-cased identifier. A parameter named htmlReader is an example of a long acronym used as the first word of a camel-cased identifier.
If you were checking names via StyleCop, you could use StyleCop+ (custom rules) which supports configurable abbreviations list.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the naming guidelines for ASP.NET controls?
Is there a standard guidelines as to the naming convention/style that asp.net control elements should be named. I have seen some developers prefixing textboxes with txt etc. Are there any standards that should be abided by?
You can use ISO standard Naming convention or CMM level convention.
like Function name "Add"
variable name "strQuery"
Control Name "btnSubmit"
Class Name "Common"
Namespace "Sanjog.Web"
public Property Name "UniqueId"
private variable "_uniqueId"
Hope this is what you are looking for.
Prefixes like "txt" are more common with developers who came up through VB6, or learned from developers who came up through VB6. In a truly object-oriented environment such as .NET its not as necessary to prefix items to indicate their type. However, doing so it entirely a matter of personal preference, just be consistent.
There is no official standard for naming of controls.
Actually the naming convention is only for your convenience so that it can be reusable and some one who will be editing it or trying to understand it would not be a big deal for him
Now coming to the point Generally Naming conventions are followed in company level
i.e some use the prefix of textbox (like textBoxName , textBoxPassword), some txt ( like txtName). Everything is right .
It is just that all the developers in a team must follow the same and the same to be maintained through out the project.
MSDN has it covered -> MSDN Naming Guidelines
(follows an abstract from the linked page, too long to bring everything over)
Use the following three conventions for capitalizing identifiers.
Pascal case - The first letter in the identifier and the first letter of
each subsequent concatenated word are capitalized. You can use Pascal
case for identifiers of three or more characters.
For example: BackColor
Camel case - The first letter of an identifier is lowercase
and the first letter of each subsequent concatenated word is
capitalized.
For example: backColor
Uppercase - All letters in the identifier are capitalized.
Use this convention only for identifiers
that consist of two or fewer letters.
For example: System.IO, System.Web.UI
You might also have to capitalize identifiers to
maintain compatibility with existing, unmanaged symbol schemes, where
all uppercase characters are often used for enumerations and constant
values. In general, these symbols should not be visible outside of the
assembly that uses them.
Anyway, as long as everyone working on a project follows the same convention, you're good to go, whatever that convention is.
I am writing a code generator in which the variable names are given by the user.
Previous answers have suggested using Regex or CodeDomProvider, the former will tell you if the identifier is valid, but doesn't check keywords, the latter checks keywords, but doesn't appear to check all Types known to the code.
How to determine if a string is a valid variable name?
For instance, a user could name a variable List, or Type, but that is not desirable. How would I prevent this?
The easiest way is to add a list of C# keywords to your application. MSDN has a complete list here.
If you really want to get fancy, you could dynamically compile your generated code and check for the specific errors that you're concerned about. In this case, you're specifically looking for error CS1041:
error CS1041: Identifier expected; '**' is a keyword
You'll probably want to ignore any errors regarding unresolved references, undeclared identifiers, etc.
As others have suggested, you could just prepend your identifiers with #, which is fine if you don't want the user to examine the generated code. If it's something they're going to have to maintain, however, I'd avoid that as (in my opinion) it makes the code noisy, just like $ all over the place in PHP or guys that insist on putting this. in front of every freaking field reference.
I'm not sure there is a full API available which will give you what you're looking for. However the end result you seem to be looking for is the generation of code which will not cause conflicts with reserved C# keywords or existing types. If that is the case one approach you can take is to escape all identifiers given by the user with the # symbol. This allows even reserved keywords in C# to be treated as identifiers.
For example the following is completely valid C# program
class Program
{
static void Main(string[] args)
{
int #byte = 42;
int #string = #byte;
int #Program = 0;
}
}
One option here would be to have your code generator prefix the user-specified name with #. As described in 2.4.2, the # sign (verbatim identifier):
prefix "#" enables the use of keywords as identifiers, which is useful when interfacing with other programming languages. The character # is not actually part of the identifier, so the identifier might be seen in other languages as a normal identifier, without the prefix. An identifier with an # prefix is called a verbatim identifier. Use of the # prefix for identifiers that are not keywords is permitted, but strongly discouraged as a matter of style.
This would allow you to check for the main keywords, and deny them as needed, but not worry about all of the conflicting type information, etc.
You could just prepend a # character to the variable - for instance, #private is a valid variable name.