Archive

Posts Tagged ‘Programming’

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.

Advertisements

Suggestion: on Duck Typing and C#/.NET

My comment at:

http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/4272089-support-implicit-interfaces-for-code-reuse

It would be nice indeed if one could define at the client object’s side a static interface that is a subset of the methods of a server (or serving if you prefer) object (it is only the view of the server that the client has gained knowledge of) that has been passed on to the client

Then there could be a service (a facility I mean) that accepts the server object instance and the interface the client has defined (the duck type) and case the server object to that interface by CHECKING that the duck interface is indeed a subset of the methods the server object implements

the check if our duck interface is indeed covered by what the object to be duck-typed offers can be implemented via reflection already

the implementation could be hacked by spitting out a new object (bytecode generation) that wraps each property/method of the object to be duck-typed and calls into the original object, but it would be much better if there was support in the compiler for that (viewing an object via an interface that is compatible to it in functionality, not in strong typing concept)

…when I say support in the compiler, I mean to avoid the proxying layer (of course security should also be considered carefully when implementing such a thing, in case there are pitfalls)

 

A very interesting article on the subject showing how to do DuckTyping in .NET is:

http://www.codeproject.com/Articles/122827/DynamicObjects-Duck-Typing-in-NET

 

Not sure if in the time that has passed (5 years) there have been any DuckTyping-specific additions at C#/.NET

Suggestion: Add support for constants in C# (and VB.net etc.) interfaces

It is rather unfortunate that C# doesn’t support constants in interfaces, whereas Java does.

If IL (intermediate language) that C# usually compiles to (when not using AOT that is like in .NET Native or Xamarin iOS) doesn’t support this, then the compiler could create a special sealed class to carry the constants.

Then, wherever they’re used via the interface it could get them via that class. This would happen internally without the programmer noticing. The programmer should be able to access the constants using:

ISomeInterface.SomeConstant

SomeClass.SomeConstant, where SomeClass implements ISomeInterface

just SomeConstant when the code is inside the body of SomeClass that implements the ISomeInterface

just SomeConstant when there is a “using static” statement (that newer C# has introduced) like “using static ISomeInteface” or “using static ISomeClass”

image

You can vote up this suggestion at:
http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/10724265-add-support-for-constants-in-c-and-vb-net-etc

Suggestion: Define once and reuse result type of method inside its body

It would be nice if one could rewrite this C# snippet:

public SortedDictionary<string, UObject> GetObjects()
{
SortedDictionary<string, UObject> result = new SortedDictionary<string, UObject>();
using (ReadTransaction xact = namingSchema.ReadTransaction())
foreach (ObjectName.RowType row in ObjectName.object_name_(xact))
result.Add(row.name_, row.object_);
return result;
}

 

in a more concise form like:

 

public T GetObjects() where T=SortedDictionary<string, UObject>
{
T result = new T();
using (ReadTransaction xact = namingSchema.ReadTransaction())
foreach (ObjectName.RowType row in ObjectName.object_name_(xact))
result.Add(row.name_, row.object_);
return result;
}

 

In case you wonder what this code is doing, it is getting Ubisense objects and their names, for the whole sample see http://UbisensePositioning.codeplex.com

You can vote on this suggestion at:

http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/10724304-define-once-and-reuse-result-type-of-method-inside

Suggestion: Allow new in C# without giving Type

This is a suggestion I’ve just sent in via Visual Studio’s “Send a frown” feature:

Instead of writing statements like:

List<CultureInfo> result = new List<CultureInfo>();

in C# I’d prefer to be able to write

List<CultureInfo> result = new ();

inside the () one would be able to pass contructor parameters and also they should be able to use

SomeClass v = new (someParam) { someProperty = …, otherProperty = … };

syntax, that is be able to initialize properties of the class

What I mean is that I want to omit the type name after the new, since it is deduced from the type I have given to the new var.

Doing

Type v = new (…){…};

is more general from the alternative of doing

  var v = new Type(…){…};

since you would be also able to even do

  someCollectionType.Add(new (…){…});

to add a new member to a typed collection

and also would be able to do

SomeMethod(new (…){…})

where the Type would be deduced from the param of the method (obviously if it is not overloaded with more versions with just 1 param)

Update:

In fact, now that I think of it again, the concept of anonymous types in C# could be merged with the suggested one, making the (…) optional if no constructor parameters are to be used (in anonymous types you only give the {…} part with the properties’ initialization).

The compiler would then resort to making a new anonymous type only if it can’t deduce a type from the usage context.

Of course if the (…) part (constructor parameters) are given, it would never try to make an anonymous type if it can’t find a matching type to instantiate with the respective constructor signature to call.

Have uploaded this for voting up at:

http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/9453546-allow-new-in-c-without-giving-type

Suggestion: Case adaptive text replacement in Visual Studio editor

Have again suggested this long before to Visual Studio team, but since Visual Studio 2013 has a “Send a Frown” feature, I’ve sent it again with some suggestions on how it could be implemented.

I need some clever replace in cases like that one shown in the screenshot below, where I have the implementation of a Sounds property and want to clone that and rename it to Music (this is useful when repeating a coding pattern, but more importantly can use this when refactoring code and need to rename something).

When doing replace on the selection, replacing "sounds" to "music", I want the word/target phrase to detect the casing of the source word/phrase and keep the same casing style, that is:
– IsSoundsOn should become IsMusicOn
– soundsOn should become musicOn
– PROPERTY_SOUNDS should become PROPERTY_MUSIC

As you can understand now I have to do 3 replacement operations, having selected the option "Case sensitive":
– Sounds to Music
– sounds to music
– SOUNDS to MUSIC

I’d rather have an option "Case adaptive" or something like that (marketing people might call this "Smart replace").

 

image

 

Implementation-wise, every time it detects the source text (case insensitive search), it would check if it is found in one of the following casings:
– first letter non-capital
– first letter capital
– all letters small
– all letters capitals

and when replacing with the target text it would apply the same casing state to it (affecting just the first letter of the target or all letters depending on which of the above casing states were detected for the source string at each position it was found in the source text)

Fix: Visual Studio opens class diagram in XML editor with double click

Recently, to save myself sometime after having renamed some interfaces/classes in the ClipFlair project sourcecode, I right-clicked one of the class diagrams (.cd files) in it at Visual Studio’s “Solution Navigator” (this is an enhanced Solution Explorer addon) and using “Open With…” I opened up the diagrams with the XML editor to do a rename-all operation for the respective class names.

However, after saving the project I found out that from then on, that specific .cd file was opening up as XML file when double-clicked instead of opening up as a Class Diagram in the respective designer pane. Using Open With dialog would open it as a Class Diagram when asked to specifically, but using the checkbox to always open up as Class Diagram wouldn’t help fix the double-click problem for that specific .cd file (others would open up fine as class diagrams, not as XML files, when double-clicked).

I just managed to fix that issue by right clicking the file node in solution navigator’s tree and and excluding that file from the project (not deleting!), then saving the project, closing the solution containg the project and adding the file (via “Add existing file”) again after having reopened the solution. I could also possibly have right clicked selected “Unload project” after saving it and then select to reload it again, think that would have worked too.

Using VisualHG addon for Visual Studio I commited the changes to the Mercurial repository used by ClipFlair on Codeplex, which showed me that the file difference that did the fix was the following in the .csproj project file:

   <ItemGroup>
     <None Include="Diagrams\Windows.cd" />
-    <None Include="Diagrams\Windows.Views.Interfaces.cd">
-      <SubType>Designer</SubType>
-    </None>
+    <None Include="Diagrams\Windows.Views.Interfaces.cd" />
     <None Include="Diagrams\Windows.Views.ViewModels.cd" />
   </ItemGroup>

 

That is instead of that marked-as-bold entry above (marked by the diff tool with – prefix), the line marked with + prefix should be used instead. This is obviously some bug in Visual Studio 2010, it’s nice to know though that you can easily take the project offline and edit the .csproj to fix it (or remove the .cd file, save the project, reload it and add the file again).

%d bloggers like this: