Archive

Posts Tagged ‘C#’

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.

Categories: Posts Tags: , , , , , ,

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 (= or OP=), and it can return an lvalue. This means that expressions like q ? a : b = c and (q ? a : b) = c are both legal and are parsed differently, the former being equivalent to q ? 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:

image

instead of this one:

image

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:

https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/7474789-add-condition-to-foreach-in-statement

Categories: Posts Tags: , , , , ,

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

C#SuggestionObjectModifiers1

 

and currently I’m forced to write this which is way more verbose:

C#SuggestionObjectModifiers2 

 

If you like this suggestion please vote for it at:

https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/13804794-suggestion-add-instance-modifiers-to-c-and-othe

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:

http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/11038227-if-should-accept-bool

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.

%d bloggers like this: