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( stri开发者_Python百科ng 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.
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;
}
For the logic and
and or
and
is:
&&
while or
is:
||
So, an if statement with and
in it would look like this:
if ((a != null)&&(a !=""))
{
Console.Write(a);
}
And an if statement with or
in it would look like this:
if ((b != null)||(b >= 5))
{
Console.Write(b);
}
For the template, you could Export a *.cs file as a template. It is under Project>Export Template...
(I was using VisualStudios 2017)
Hopes this helps.
精彩评论