Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio Project/Item Template Parameter Logic

Since I have only seen a few posts on the topic but no in-depth explanation of the logic for parameters in templates for Visual Studio, I figured I'd post this here.

Following the MSDN article you can add custom parameters to your template that can be altered with a Wizard if you want to alter them.

In any file of the template (other than the template file itself) you can add logic based on the parameters. There are only three keywords to be used with the logic. $if$ ( %expression% ), $else$, and $endif$. So say I have the following in a template file:

public string foo( string a ) {     return string.Format( @"foo( {0} );", a ); } 

And we want to add some logic for whether or not we want to check if "a" is null or empty

public string foo( string a ) { $if$ ( $shouldCheckForNullOrEmpty$ == true )     if ( !string.IsNullOrEmpty( a ) ) $endif$      return string.Format( @"foo( {0} );", a ); } 

Of course you may want to add the braces for the if statement so you may need more than one logic block.

So that is not too bad, but there are a few tricks to this. The $if$ check for string match, that is shouldCheckForNullOrEmpty must equal "true". It was also tempted in writing $if$ ($shouldCheckForNullOrEmpty$ == "true"), but that will not work.

Single if statements with single expressions are pretty simple so now for a bit more complex example:

public string foo( string a ) { $if$ ( $parameterCheckMode$ == ifNullOrEmpty )     if ( !string.IsNullOrEmpty( a ) ) $else$ $if$ ( $parameterCheckMode$ == throwIfNullOrEmpty )     if ( string.IsNullOrEmpty( a ) )         throw new ArgumentException(); $endif$ $endif$      return string.Format( @"foo( {0} );", a ); } 

As you may be able to tell, this is a switch statement for the parameter mode. You may note that there is no $elseif$ so you have to make it $else$ $if$ but will have to add an extra $endif$ at the end.

Lastly, I have yet to find and or or symbols for the logic. I got around this by just using the logic equivalence:

and -> $if$ ( expression1 ) $if$ ( expression2 ) $endif $endif$

or -> $if$ ( expression1 ) statement $else$ $if$ statement $endif$ $endif$

Hopefully this helps someone.

like image 510
maschall Avatar asked Jul 15 '11 15:07

maschall


People also ask

What is the role of parameter in a template?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Which is a correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.


1 Answers

This post is linked from the official Microsoft documentation for MSBuild Conditions as having examples of usage. The syntax for MSBuild conditions is not exactly equivalent to the way templating $if$ statements work but it's a close approximation. However, it seems the examples here are now obsolete or were never completely accurate to begin with. After some extensive testing I have found the following to be true in regards to templating $if$ statements:

$if$ statements can never be nested. The reason for this is the way in which the templating engine handles the case of an $if$ statement evaluating to false. When an $if$ expression evaluates to false the engine will parse until the next $endif$ it finds and remove everything in between. This means when there is a nested $if$ statement, that will be the first $endif$ that is reached and the nested $if$ expression will be removed before processing. The same is true when using $else$. There are a few misleading examples in the "question" above that will only work in the case that the outer $if$ statement evaluates to true. Consider the following example where the outer $if$ statement does not evaluate to true:

public void foo() {     string str = "";      $if$ ($true$ == false)     str = "foo";      $if$ ($true$ == true)     str = str + "bar";     $endif$ //inner      $endif$ //outer      return str; } 

The result of running this template would be the following:

public void foo() {     string str = "";      //inner      $endif$ //outer      return str; } 

As you can see, everything after the first $endif$ is left in the code. I've come up with a suitable workaround that involves using a combination of the & operator and serial if statements.

There is a logical & operator that can be used within a single if statement. The syntax is as follows:

$if$ ($foo$|$bar$ == true|false) 

This will evaluate as $foo$ == true && $bar$ == false. It is valid to use more than two operands, e.g. $foo$|$bar$|$baz$|... == true|false|etc|.... The caveat to this usage is that you can only use a single operator type for all comparisons in the statement (==|!= is not valid). I was unable to find anything comparable to an Or operator.

Putting it all together. The & operator can be used with a series of if statements to create a simulated nested-if environment. The following example shows 3 levels of nesting if(foo){...if(bar){...if(baz){...}...}...}:

public void foo() {     string str = "";      $if$ ($ext_foo$ == true)     str = "foo";     $endif$$if$ ($ext_foo$|$ext_bar$ == true|true)     str = str + "bar";     $endif$$if$ ($ext_foo$|$ext_bar$|$ext_baz$ == true|true|true)     str = str + "baz";     $endif$$if$ ($ext_foo$|$ext_bar$ == true|true)     str = str + "bar";     $endif$$if$ ($ext_foo$ == true)     str = str + "foo";     $endif$      return str; } 
like image 96
Exercising Daemons Avatar answered Sep 29 '22 18:09

Exercising Daemons