Previously, I've spoken about the new multi-targeting rule that shipped in Visual Studio 2008 SP1 and FxCop 1.36. This rule helps to prevent users from inadvertently taking a dependency on a .NET service pack. Unfortunately, it shipped with a bug that when targeting .NET 3.5, prevented it from firing on usages of types and members only available in .NET 2.0 SP2 and .NET 3.0 SP2 (both installed by 3.5 SP1).
Luckily, the fix is rather simple.
In Visual Studio 2008 SP1:
- From an elevated (right-click and Run as administrator) Visual Studio command-prompt, type the following and press <ENTER>:
devenv "%PROGRAMFILES%\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop\Repository\Compatibility\Desktop2.0SP2.xml"
- In the <CompatibilityEntry> element in the file that opens, change the Priority attribute from 3015 to 3515:
<CompatibilityEntry Name=".NET Framework 2.0 Service Pack 2"
Platform="Desktop"
Version="2.0.2"
Priority="3515">
- Save the file.
- From the previously opened command-prompt, type the following and press <ENTER>:
devenv "%PROGRAMFILES%\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop\Repository\Compatibility\Desktop3.0SP2.xml"
- Similar to above, in the <CompatibilityEntry> element, change the Priority attribute from 3020 to 3520:
<CompatibilityEntry Name=".NET Framework 3.0 Service Pack 2"
Platform="Desktop"
Version="3.0.2"
Priority="3520">
- Save the file.
In FxCop 1.36:
- Follow the above steps, changing the paths above from %PROGRAMFILES%\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop\Repository\Compatibility to %PROGRAMFILES%\Microsoft FxCop 1.36\Repository\Compatibility.
To verify the fix:
- In Visual Studio, start a new C# WPF Application, and paste the following code in the code-behind of App.xaml:
public partial class App : Application
{
System.ComponentModel.DateTimeOffsetConverter field1;
System.Windows.Data.BindingGroup field2;
}
- In Solution Explorer, right-click on the project and choose Run Code Analysis.
- If the above steps were followed correctly, you should see warnings similar to the following:
This will be fixed in a future release of Visual Studio.
Thanks to Andrew Smith for bringing this my attention.
We've dropped a new version of the Managed Extensibility Framework over on our CodePlex site.
Some highlights since our last drop:
- New license (MS-PL) - redistribute, modify, or fork the source on any platform.
- Container re-factoring - we've refactored the container, pulling out its internals (such as the composition engine) into separate re-usable classes.
- Unit tests - apparently some customers prefer reading tests over docs - go figure
- Plus a lot more, such as caching, primitives cleanup and performance enhancements.
Check it out.
You may have already read Justin Van Patten's post about the upcoming breaking changes to the String class for .NET 4.0. This change will affect the behavior of the String.StartsWith, String.EndsWith, String.IndexOf and String.LastIndexOf methods by changing them to perform an ordinal (byte-for-byte) comparison by default instead of a culture-sensitive comparison using CultureInfo.CurrentCulture. In addition, the default overloads of String.ToUpper, String.ToLower, Char.ToUpper and Char.ToLower will be changed to use CultureInfo.InvariantCulture instead of CultureInfo.CurrentCulture.
How does this change affect me?
If you are using an overload of one of the above methods that does not take a StringComparison or CultureInfo as a parameter, then your application or library will be affected when you move it to .NET 4.0. String.Compare and String.CompareTo are not being changed.
An example of the kind of behavior change you could expect, is the following:
static void Main()
{
int index = "encyclopædia".IndexOf("encyclopaedia");
Console.WriteLine(index);
}
On versions previous to .NET 4.0, this will output 0 when the user's current locale is set to some cultures, such en-AU, English (Australia), and -1 when the user's current locale is other cultures, such nn-NO, Norwegian, Nynorsk (Norway).
However in .NET 4.0, the above comparison will always output -1, regardless of the user's current locale.
Why was this change made?
The comparison methods on the String class have always been a little schizophrenic; some methods, ==, String.Equals and String.Contains for example, perform an ordinal comparison by default, whereas the above methods, as well String.Compare and String.CompareTo, perform a culture-sensitive comparison. Because they use the current culture, the default culture-sensitive comparisons can also vary between systems, users and even during the same application session. Which, as pointed out in Justin's post, can lead to security vulnerabilities in applications that make security decisions using the default overloads. The planned breaking changes bring the majority of these methods inline with each other to have the same default behavior.
How do I find and fix these comparisons?
To start, you should run FxCop or Visual Studio Code Analysis over your code base. The rules Specify StringComparison and Specify CultureInfo will fire on call sites that do not explicitly specify a StringComparison or CultureInfo. Specify ordinal StringComparison will fire when you use invariant culture instead of ordinal to compare, which is almost always wrong.
To help determine the correct StringComparison or CultureInfo to use, you cannot go past the excellent article New Recommendations for Using Strings in .NET 2.0. In particular, the section under Choosing a StringComparison Member for Your Method Call provides a table detailing common operations and comparisons to use.