Archive
HowTo: Use latest C# features in MVC5 Razor views (.cshtml)
Having recently updated an ASP.net MVC web app from MVC4 to MVC5 and from .NET 4.5 to .NET 4.7.2 I was expecting Razor views (.cshtml files) to use the latest C# compiler, especially since at Properties/Build/Advanced option for the web project one read “C# latest major version (default)”.
However that was not the case and trying to use newer C# language features like the ?. ternary conditional operator or interpolated strings (or nameof etc.) would show errors like
Feature ‘interpolated strings’ is not available in C# 5. Please use language version 6 or greater.
Luckily there is a workaround for using the latest C# compiler in MVC5. Just need to add the NuGet package https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/ to one’s project as explained at https://dusted.codes/using-csharp-6-features-in-aspdotnet-mvc-5-razor-views. Alternatively one could move their project to ASP.net Core, which is a more drastic move though.
After doing it I started seeing Intellisense issues in .cshtml like:
The type ‘Expression<>’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Core …
Tried to add the System.Core assembly to the project, but wasn’t allowed (it said the Build system was adding it). Adding System.Core as a NuGet package would mean moving to .NET Core which I wasn’t ready to try with that project yet.
Seems there was an easy solution to that, just closed and reopened the Visual Studio solution and did a Rebuild and all was fine after that.
Gotcha: use parentheses around ternary op conditional expressions
Just came across the following case in C# that puzzled me momentarily, especially since the strings involved were long enough and the expression was broken on multiple lines:
bool flag = true;
string test1 = flag? "xa" : "xb";
string test2 = "x" + (flag? "a" : "b");
string test3 = "x" + flag? "a" : "b";
The test3 case fails since the compiler tries to evaluate the "x" + flag expression at the left side of the operator ?, complaining that it cannot implicitly convert string to bool.
e.g I accidentally produced the following wrong code while I was trying to refactor some third-party code to make it more readable:
string test3 = “some long string here” +
(someFlag)?
“some other long string”
:
“some alternative long string”;
whereas the correct was:
string test3 = “some long string here” +
( (someFlag)?
“some other long string”
:
“some alternative long string” );
The correct one needs the whole conditional expression enclosed in parentheses. In fact, the parentheses around (someFlag) can be skipped. In usually prefer them visually, even when I use just a boolean variable instead of a more complex boolean expression, but in case like this one the x + (someFlag)? a : b can be confusing to the reader of the code, not seeing x + (someFlag) will be treated as the conditional instead of someFlag.
Luckily the C# compiler is deterministic enough and not trying to imply meaning from one’s wrong syntax. Had it been some futuristic AI-based interpreter, well, it might have gotten confused there too.
To avoid this confusion in the first place, probably one could have designed a (bool)?x:y operator instead with parentheses being required around the boolean expression, but people coming from other languages (say C++) might then end up writing bool && (bool)?x:y and expect the condition to be bool && (bool) instead of just (bool), so even that syntax would be problematic.
Speaking of other languages, quoting from Wikipedia article on ternary operator:
C++
Unlike in C, the precedence of the
?:
operator in C++ is the same as that of the assignment operator (=
orOP=
), and it can return an lvalue. This means that expressions likeq ? a : b = c
and(q ? a : b) = c
are both legal and are parsed differently, the former being equivalent toq ? a : (b = c)
.
So confusion even between languages that share a C-style syntax might not be avoided.
Suggestion: add optional “where” clause to “foreach” statement in C#
Wouldn’t it be nice if I could use in C# the following syntax?
for (SomeType repeaterVariable
in SomeEnumerable
where someBooleanExpressionOfRepeaterVariable)
doSomethingUsingRepeaterVariable;
e.g. use this one:
instead of this one:
BTW, if you wonder what FixTime does, it prepends 0: to time strings to make sure they are of format h:m:s.f
Have added this as a comment to another person’s suggestion that I see has similar format, so please vote for that one:
Suggestion: Add instance modifiers to C# (and other languages)
I’d like to be able to do
someFunctionReturningY(x){ somePropertyOfY=4; … }.DoSomething();
It should also support casting without needing parentheses in the following type of statement:
Z zzz = (Z)functionReturningY{somePropertyOfZ=…; … };
The same pattern should work for enums too apart from object instances. It is inspired by initializers in C#, e.g. var x = new Test(){someProperty=…}. It’s just a generalization of the same pattern.
E.g. at the following scenario I want to modify an object that GetMetadataFromUI function returns
and currently I’m forced to write this which is way more verbose:
If you like this suggestion please vote for it at:
Suggestion: If and while etc. clauses should accept bool? in C#
At TrackingCam app (http://TrackingCam.codeplex.com) I have the following WPF code, where cbTrackingPresenter is a CheckBox control defined in my MainWindow’s XAML:
private void cbTrackingPresenter_Checked(object sender, RoutedEventArgs e)
{
if (cbTrackingPresenter.IsChecked == true)
StartTrackingPresenter();
else
StopTrackingPresenter();
}
Note the (redundant in my opinion) == true pattern used there. If the == true is omitted, you get the compile-time error "CS0266", with message "Cannot implicitly convert type ‘bool?’ to ‘bool’. An explicit conversion exists (are you missing a cast?)"
Why not make the "if" clause (and "while" and any clause accepts a boolean/condition) more clever and have it accept bool? too? It would only fire the condition if the value is "true" (not if it is false or null) in that case.
You can vote for this suggestion at:
HowTo: show inner exception message if available, else outer one
Sometimes when you catch an exception in .NET, the message it prints out isn’t very informative, since it is wrapping another exception that had been thrown a bit inner in the code. That exception is in that case accessible via InnerException of the Exception instance.
That inner exception is also an Exception, so one would like to use its Message instead of the outer exception’s one, if an inner exception exists and, only if an inner exception doesn’t exist use the caught exception’s message. Here’s a clean-looking pattern I’ve coined up to achieve this while working on the TrackingCam application:
try
{
//…
}
catch (Exception e)
{
MessageBox.Show((e.InnerException ?? e).Message);
}
the ?? operator returns e.InnerException if it is not null, else falls back to returning e. Those two results are both of type Exception, so you can use Message on them, by putting the ?? operator’s expression in parentheses.
Suggestion: C# static extension methods invokable on class type too
it would be nice if C# supported syntax like:
public static DependencyProperty Register(static DependencyProperty x, string name, Type propertyType, Type ownerType, FrameworkPropertyMetadata typeMetadata)
that is static extension methods for classes, that can be invoked without a class instance (just with the class type), apart from normal extension methods that can be invoked on a class instance.
Then for example I could use it in Silverlight to add to its DependencyProperty class some extra WPF syntax that it currently misses, in order to increase code portability. It would wrap Dr.WPF’s implementation of value coercion for Silverlight’s DependencyProperty. I have the related code at my Compatibility library (http://Compatibility.codeplex.com) and respective NuGet package (http://nuget.org/packages/Compatibility), but the syntactic sugar is missing to achieve source code portability (via WPF and Silverlight projects that include common files via file links) without changes.
Note the "static DependencyProperty" parameter instead of the "this DependencyProperty" one that is used in C# extension methods (or else instead of static maybe they could use other keyword like type or typeof there, but I feel static is more appropriate).
Related discussion:
http://stackoverflow.com/questions/866921/static-extension-methods
http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class
Also see https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f where somebody mentions "static extension properties" apart from "extension properties". Indeed it is natural that if static extension methods are to be allowed in the future, static extension properties should be added too (to extend a type with [attached] static properties)
You can vote for a related suggestion here:
Suggestion: Initialize multiple fields to same value at constructor call in C#
When using http://github.com/zoomicon/ZUI I would like to write:
FloatingWindow window = new FloatingWindow()
{
Content = display,
Title = IconText = title
};
but I have to write:
FloatingWindow window = new FloatingWindow()
{
Content = display,
Title = title,
IconText = title
};
instead. For consistency, I’d prefer that it supported such assignment. Now it thinks IconText is some external field or similar
you can vote for this suggestion at:
HowTo: Remove unused references and using clauses in Visual Studio
I recently posted a list of the VS2015 extensions I use on my main machine at: https://zoomicon.wordpress.com/2015/11/13/visual-studio-2015-extensions-i-use/
From that list of extensions I use the Productivity Power Tools one, it has a "Power Commands > Remove and Sort Usings" action that one can right click and run on the whole solution. Much easier than opening it for each
There is another nice extension called ResolveUR that is not available for VS2015, but only for VS2013 (think you can edit its .vsix and make it work for it too though, see the process for other similar extension explained at https://devio.wordpress.com/2014/12/03/remove-unused-references-with-visual-studio-2013/). I usually open up the solution in VS2013 too just to run that. Resharper also has such functionality as shown at:
https://www.jetbrains.com/resharper/help/Refactorings__Remove_Unused_References.html
Alternative is to use the Copy References extension and right click a reference under the References subtree of a project, then select "Copy Reference", then Remove the reference and rebuild that project. If rebuild fails, then right click at the References again and select Paste Reference. Then repeat till you remove all references that are not needed
In fact one should FIRST remove all unused using clauses and THEN remove unused references. That is because some files like App.xaml.cs, AssemblyInfo.cs may have using clauses that they don’t really use. So unless those using clauses are removed, the compiler thinks respective references to assemblies those namespaces were at are needed