Working within Visual Studio 2015, I have a conditional check to the effect of:
if(String.IsNullOrWhiteSpace(stringToTest))
And I saw an IDE001 quick tip or action suggesting that the "Name can be simplified" with a suggested correction of:
if(string.IsNullOrWhiteSpace(stringToTest))
With the only difference being to use string instead of String.
MSDN examples use an uppercase S with String, and this SO answer clarifies that "string is an alias in C# for System.String. So technically, there is no difference."
And to be clear, my question relies upon the answers within String vs. string, but I have a different question than what is asked there.
Also related is this SO question, although the answers there don't really address the question. That particular question is very similar to mine, however it is marked as a duplicate of the other SO question I noted. And there is a comment by the OP indicating this is brand new behavior only seen in 2015.
My Question
My question is that if the two variable types are equivalent, and MS examples use the upper case version, why am I seeing quick actions to use the lower case version? Was there a change in the .NET 4.6 framework and VS2015 to encourage using the lower case version? It doesn't seem like I should be seeing that type of a tip.
Well, as smarter than me have noted there's actually no difference in the compiling level, and like you (and like JohnyL as you'll see ;), I also thought it's a bug and got to what's leading me to my answer:
why am I seeing quick actions to use the lower case version?
Taken from this informative (and funny) bug discussion, these are the main points for this feature:
It doesn't just change the letter case, it replaces the String type name with the string keyword. The fact that the 2 happen to differ only by case is a coincidence. There are cases where the number of characters is different (Int32 -> int) or the name is completely different (Single -> float).
Lower case names are easier to type.
For people that actually prefer the consistent format of string in the code (it's probably dependent on other languages you code in and their conventions) this feature helps change existing source code to be consistent.
string is also a keyword with a well defined meaning while String's meaning may be different depending on context.
Was there a change in the .NET 4.6 framework and VS2015 to encourage using the lower case version?
As far as I've read, No.
BTW, you can change this behavior to suit your preference in Tools > Options > Text Editor > C# > Code Style -> Uncheck "Prefer intrinsic predefined type keyword in member access expressions".
I am only speculating, but it seems to me that the quick tip is intended to help you simplify System.String to string, ignoring the fact that your usings have made it redundant, at least in terms of character-counting.
Call it a bug (albeit an extremely minor one) or at least the IDE getting overzealous. One could argue that this is a valid simplification in a broader sense, particularly if you are to use these short "aliases" consistently in your code. As a C++ developer, I'm not really seeing it, but there you go.
There is no difference for compiler but IDE quick fixes are also used for ensuring good styling (e.g. naming conventions). You are programming in C# so you're expected to use its features (in this case - bultin type alias).
I think you are using int instead of Int32, right? So the same is for string and String. Although there is no real difference in length for string technically this is still similar case.
I have a suspicion that the primary reason for changing System.String to string is because it is regarded as a primitive .NET. And since all primitives have aliases - System.Int32 -> int, System.Char -> char etc., for consistency-sake, "string" is treated the same. Looking through all sorts of other MSDN documentation you'll see the two being used interchangeably; I think that's a simple oversight on their part.
Whether its warranted or not, I'm still going to use string over String as the quick tips suggest. Sounds like an example of Grandma's Cooking Secret, but is there a reason to change that behavior in this case?
Related
I have a C# assembly that uses "$(FrameworkSDKDir)\Bin\NETFX 4.0 Tools\tlbexp.exe" "$(OutDir)My.dll" /out:"$(TLBDir)My.tlb" so that I can call it from native components
I am looking at
.tlh generated on 2 machines is different and it appears to be a similar problem, but my difference is in visual2010 the tlh is generated using one case, and in 2012, it is generated using a different case.
Even more interesting this just happened a day ago. I have a build from the 18th that worked just fine, and the code has not changed in either solutions for many days.
Any thoughts before i continue down the /Names option?
I cannot easily tell you what to do to solve this problem, just highlight why this is happening. It doesn't have much to do with Tlbexp.exe, it is generic behavior implemented in the type library support built into Windows.
It has a tricky problem to solve, it cannot make any assumptions about the kind of language that was used to generate the types. The troublemakers are languages that are case-insensitive, Visual Basic being the prime example. Also the original language for which type libraries were invented. The issue is that it may emit names that can have different casing in different declarations but identify the same type. If the type library would use the same casing then it could only ever be consumed by a language-insensitive compiler.
So it does something about it, the algorithm it uses can at best be described as crude however. It looks at any name, regardless of what part of a declaration it is used, then forces the casing of any subsequent same name it encounters to the same casing. The usual big surprises are caused by names of function arguments. They can change the name of a function if it happens to match. So an "item" argument, pretty common, can spoil the name of an "Item" property. Or the other way around.
The wild-card here is order, I suppose that could be half an explanation.
Best way to address the problem is to change the name so there is no longer a collision. You have no trouble finding them, it is the one that changed casing. You may have to iterate a few times to find them all. Given that it is usually the name of an argument that causes this, feel free to change the argument name. Just put an underscore after it for example, it doesn't break binary compatibility nor the client code.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between String and string
I'm using string for a variable, like this
string myString = "test";
And I'm using String if I want to use some methods(?) of the Class String
String.Format...
I thought this is looking better. Buy some people are doing stuff like
String myString;
string.Format...
Its working. But I don't like this. How can I tell them to stop? Is there "C# rule" for stuff like this? The same thing for int,Int; char,Char; ...
string is a C# alias to System.String.
If writing C#, you should be using the alias, so string.Format and string myString.
Both end up compiled to the same IL and mean the same thing, but C# has its idioms and using the type alias is part of them - in the same way that you would use int and not System.Int32.
Coding guidelines are an important thing if you are working on bigger projects and ensure that you can easily read code written by any of the developer in your team.
Unfortunately there isn't any official guideline on how you should format your C# code. Microsoft itself encountered the problem while developing the .NET framework and developed an internal set of style guidelines which grew into a full fledged program called StyleCop which has a default rule set with sensible settings.
According to these rules you should always use string instead of String:
string xyz;
string.Format();
The rules is the following:
SA1121 - UseBuiltInTypeAlias - Readability Rules
The code uses one of the basic C# types, but does not use the built-in
alias for the type.
Rather than using the type name or the fully-qualified type name, the
built-in aliases for these types should always be used: bool, byte,
char, decimal, double, short, int, long, object, sbyte, float, string,
ushort, uint, ulong.
A recommended reading is the history of StyleCop you can find here:
http://stylecop.codeplex.com/wikipage?title=A%20Brief%20History%20of%20CSharp%20Style&referringTitle=Documentation
It explains some of the problems you encounter with different people from different backgrounds working on the same code base and how they developed the rule set.
We recently implemented StyleCop in our own project and although it is a lot of work to really follow all the rules, the resulting code is much more readable. It also has a fairly good ReSharper integration which allows you to do many fixes automatically if you use ReSharper.
I usually express this as, "If there is an identical primitive type in the language, prefer it." In your specific case, which style to use is a preference rather than something that has major impacts to functionality. What is important is that whatever style is chosen is consistently applied by everyone in your team.
I am currently testing out Ndepend, and it gives me a warning that assemblies should be marked as CLSCompliant.
Our project is all C#, so it is not really needed.
What I am wondering is: are there any negative effects of marking a dll as clscompliant or should I just disable the warning?
Note I am not asking what CLSCompliant means that is covered here: What is the 'CLSCompliant' attribute in .NET?
This is one of those subtle cases... CLS compliance is probably of most importance to library authors, who can't control who the caller is. In your case, you state "our project is all C#", in which case you are right: it isn't needed. It adds restrictions (for example, on unsigned types) which might (or might not) affect representing your data in the most obvious way.
So: if it adds no value to you whatsoever, then frankly: turn that rule off. If you can add it for free (no code changes except the attributes), then maybe OK - but everything is a balance - effort vs result. If there is no gain here, don't invest time.
If you are a library author (merchant or OSS), then you should follow it.
There are several C# features that are not CLS compliant, for example unsigned types. Since several languages are case insensitive, there must be no types and members that differ only by case, e.g. MyObject and myObject, and several other features. Thus, if you don't plan to work with other .NET languages there is no reason to mark your code as CLSCompliant.
The only negative effects would be compiler errors when your code is marked as CLSCompliant, but it is not.
Do default parameters for methods violate Encapsulation?
What was the rationale behind not providing default parameters in C#?
I would take this as the "official" answer from Microsoft. However, default (and named) parameters will most definitely be available in C# 4.0.
No, it doesn't affect encapsulation in any way. It simply is not often necessary. Often, creating an overload which takes fewer arguments is a more flexible and cleaner solution, so C#'s designer simply did not see a reason to add the complexity of default parameters to the language.
Adding "Another way to do the same thing" is always a tradeoff. In some cases it may be convenient. But the more syntax you make legal, the more complex the language becomes to learn, and the more you may wall yourself in, preventing future extension. (Perhaps they'd one day come up with another extension to the language, which uses a similar syntax. Then that'd be impossible to add, because it'd conflict with the feature they added earlier)
As has been noted, default parameters were not a prioritized feature, but is likely to be added in C# 4.0. However, I believe there were excellent reasons not to include it earlier (in 4.0, as I've understood it, itäs mostly to support duck typing styles of programming where default parameters increases type compatibility).
I believe excessive parameter lists (certainly more than 4-5 distinct parameters) is a code smell. Default parameters are not evil in themselves, but risk encouraging poor design, delaying the refactoring into more objects.
To your first question - no, it's exactly the same as providing multiple overloaded constructors. As for the second, I couldn't say.
Default parameters will be included in C# 4.0
Some reading material about it:
click
click
It also seems that the author of this post will publish an article in the near future on the 'why' MS chooses to implement default params in C#
Here is an answer why it's not provided in C#
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
One drawback with the default parameter implementation in C# 4.0 is that it creates a dependency on the parameters name. This already existed in VB, which could be one reason why they chose to implement it in 4.0.
Another drawback is that the default value depends on how you cast your object. You can read about it here: http://saftsack.fs.uni-bayreuth.de/~dun3/archives/optional-parameters-conclusion-treat-like-unsafe/216.html .
In a recent VB.NET project I adopted the naming conventions I'm used to using in C#. Namely, often calling a variable the same name as the class it references, only with a different case, e.g.
Foo foo = new Foo(); // C#
Dim foo As New Foo() ' VB.NET
I find this is often the clearest way to write code, especially for small methods. This coding style obviously works fine in C#, being case sensitive, and because of the syntax highlighting provided by Visual Studio, it is very easy to see that the class name and the variable name are different.
However, to my surprise, this also worked fine nearly 100% of the time* in VB.NET. The only issue was that the variable name then appeared to take on a multiple identity. Namely it could be used to call both instance methods and Shared (static) methods of the Foo class. This didn't really cause any problems though, it just meant that Intellisense would provide a list containing both static and instance methods after you hit the '.' after the variable name.
I found, again to my surprise, that this didn't actually lead to any confusion in my project, and it's been very successful so far! However I was the only person working on this particular project.
Here is a slightly longer example:
Dim collection as Collection = New Collection()
For Each bar As Bar in Bar.All()
collection.SomeInstanceMethod(bar)
Next
collection.SomeSharedMethod()
* The only issue I found with this was that sometimes the 'Rename' refactoring tool got confused, i.e. when renaming a class it would rename the variables with the same name as the class as well, in their declaration lines (Dim foo As...), but not the other references to that variable, causing compiler issues (duh). These were always easy to correct though.
Another small annoyance is that the VB.NET syntax highlighter doesn't highlight class names any differently than variable names, making it not quite as nice as when using it in C#. I still found the code very readable though.
Has anyone else tried allowing this in a team environment? Are there any other potential issues with this naming convention in VB.NET?
Although VB is case-insensitive, the compiler is intelligent enough to not being confused between the object-instance and the class.
However, it's certainly very dangerous and wrong to use the same name in a case-insensitive language! Especially if other programmers are working on that project.
I have to move back and forth between VB and C#, and we consider this poor practice. We also don't like letting variable names in C# differ from their type only by case. Instead, we use an _ prefix or give it a more meaningful name.
Whenever you start a new language it's inevitable you'll notice a bunch of things that are different and miss the old way of doing things. Often this is because you are initially unaware of different features in the other language has that address the same problem. Since you're new to VB, here are a couple notes that will help you get things done:
It's not 100% correct to say that VB.Net is case-insensitive unless you also make the point that it is case-aware. When you declare an variableidentifier, the IDE will take note of what case you used and auto-correct other uses to match that case. You can use this feature to help spot typos or places where the IDE might be confused about a variable or type. I've actually come to prefer this to real case-sensitive schemes.
VB.Net imports namespaces differently. If you want to use the File class, you can just say IO.File without needing to import System.IO at the top. The feature especially comes in handy when learning a new API with a few nested namespace layers, because you can import a top-level section of API, type the next namespace name, and you'll be prompted with a list of classes in that namespace. It's hard to explain here, but if you look for it and start using it, you'll really miss it when going back to C#. The main thing is that, for me at least, it really breaks my flow to need to jump to the top of the file to add yet another using directive for a namespace I may only use once or twice. In VB, that interruption is much less common.
VB.Net does background compilation. The moment your cursor leaves a line, you know whether or not that line compiles. This somewhat makes up for not highlighting class names, because part of why that's useful in C# is so you know that you typed it correctly. VB.Net gives you even more confidence in this regard.
I'm going to differ with the rest of the answers here... I don't think there is any problem with doing this. I do it regularly, and have absolutely 0 problems resulting from it.
If you use lowercase for the variable name you can easily differentiate the variable from the type, and the compiler will not confuse the two identifiers.
If you delete the variable declaration, the compiler will think other references to this variable now refer to the type, but it's not really a problem because those will be tagged as errors.
I have done the same thing in the past. I'm starting to move away from it though because Visual Studio will occasionally get confused when it auto formats the code and changes the casing on my static method calls to lower case. That is even more annoying than not being able to differentiate the variable and class names by case only. But, purely from technical perspective it should not cause any issues.
As Moayad notes, the compiler can tell the difference--but it's bad practice that can lead to maintenance issues and other side effects.
A better practice all-around is to try to name the variable in the context they're being used, rather than just the type name. This leads to self-documenting code and requires fewer comments (comments are greatly abused as an excuse to write dense code).
It's only safe as long as the compiler can always tell whether Foo means the class or the variable, and eventually you'll hit a case where it can't. Eric Lippert discusses the sort of thing that can go wrong on his blog.
I use this convention all the time, and it's never been a problem. The most natural name for a variable is often the class name, and therefore that's what you should call it (Best name for an arbitrary Line? line.).
The only downside is when some tool interprets the context incorrectly. For example, visual studio 2010 beta 1 sometimes uses the class highlight on variables named the same as the class. That's a bit annoying.
Context sensitivity is much closer to how I think than case sensitivity.
Well, this isn't the final answer, and I don't think there is a definitive one, but the general opinion seems to be that it's not a good idea to use this naming convention! There must be one true way to write nice VB.NET variable names though, and I don't like any of the alternatives...
Here are links to the official Microsoft guidelines for anyone who's interested, although they don't seem to cover this particular question (please correct me if I've missed it).
Visual Basic Naming Conventions: http://msdn.microsoft.com/en-us/library/0b283bse.aspx
Declared Element Names: http://msdn.microsoft.com/en-us/library/81ed9a62.aspx
Cheers all!
VB.NET isn't case sensitive! This equates to:
Foo Foo = new Foo(); // C#
As a standard in our team environment we would use:
Dim oFoo as New Foo 'VB.NET