Visual Studio 项目/项目项模板参数逻辑

39

鉴于我只看到少数有关Visual Studio模板参数逻辑的帖子,但没有深入解释,因此我觉得在这里发布这个问题。

根据MSDN文章,您可以向模板中添加自定义参数,如果要更改它们,可以使用向导(Wizard)进行更改。

在模板的任何文件中(除了模板文件本身),都可以根据参数添加逻辑。 逻辑只有三个关键字可用。 $if$(%expression%),$else$和$endif$。 因此,假设我在模板文件中有以下内容:

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

我们想要添加一些逻辑,来确定我们是否想要检查 "a" 是否为 null 或空

public string foo( string a )
{
$if$ ( $shouldCheckForNullOrEmpty$ == true )
    if ( !string.IsNullOrEmpty( a ) )
$endif$

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

当然,你可能想要为if语句添加大括号,所以你可能需要多个逻辑块。

这并不太难,但有一些技巧。$if$检查字符串匹配,即shouldCheckForNullOrEmpty必须等于"true"。虽然写成 $if$ ($shouldCheckForNullOrEmpty$ == "true") 看起来很诱人,但这样不起作用。

单个表达式的if语句非常简单,现在我们来看一个稍微复杂一点的例子:

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 );
}

你可能已经注意到,这是一个针对参数 mode 的 switch 语句。你可能会发现没有 $elseif$ 关键字,因此你需要使用 $else$ $if$,但最后必须添加一个额外的 $endif$。

最后,我还没有找到逻辑运算符 andor 的符号。我通过使用逻辑等价来解决了这个问题:

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

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

希望这能帮助到某人。


6
问题是,为什么你要强制自己使用项目模板机制来执行这种条件语句?模板存在的目的是为了提供一个比较固定的基础起点,而不是用于创建基于用户提供的选项逻辑复杂的类(这很难维护)。 - lysergic-acid
你测试过哪些版本的Visual Studio?我一直在使用Visual Studio 2008进行尝试,虽然$parameter$替换工作正常,但是$if$/$else$/$endif$关键字似乎完全被忽略了。如果我输入类似于"$if$ ($targetframeworkversion$ == 3.5)using System.Linq;$endif$"的内容,输出结果为"$if$ (3.5 == 3.5)using System.Linq;$endif$"。 - Sean Werkema
经过大量研究,这确实适用于Visual Studio 2008,但它非常古怪,并且需要在.vstemplate文件中使用“魔法”XML指令:<VSTemplate Type="Item" Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">。请注意其中关键的3.0.0。模板中还有很多其他空格方面的古怪问题;更多信息可以在此线程中找到:http://stackoverflow.com/questions/1220389/whats-wrong-with-my-visual-studio-2008-template/1568717 - Sean Werkema
你应该以问题/答案的形式编写此内容,以帮助那些正在寻找答案的人。 - HankCa
我找不到“not”的方法。我使用的解决方法是要么使用"$else$",要么只需创建参数字符串,如“false/no”等。 - Xenial
显示剩余2条评论
2个回答

2
这篇文章是从官方Microsoft MSBuild Conditions文档中链接到的,作为使用示例。MSBuild条件语法与模板$if$语句的工作方式并不完全相同,但它们非常接近。然而,这里的示例现在似乎已经过时或者一开始就不完全准确。经过广泛的测试,我发现以下关于模板$if$语句的内容是正确的: $if$语句永远不能嵌套。原因在于模板引擎处理$if$语句计算结果为false的情况的方式。当一个$if$表达式计算结果为false时,引擎将解析直到找到下一个$endif$并删除之间的所有内容。这意味着当有一个嵌套的$if$语句时,它将是第一个被找到的$endif$,并且在处理之前会删除嵌套的$if$表达式。同样适用于使用$else$时。上面的“问题”中有一些误导性的示例,只有在外部$if$语句计算结果为true的情况下才能正常工作。考虑以下示例,其中外部$if$语句没有计算结果为true的情况:
public void foo()
{
    string str = "";

    $if$ ($true$ == false)
    str = "foo";

    $if$ ($true$ == true)
    str = str + "bar";
    $endif$ //inner

    $endif$ //outer

    return str;
}

运行此模板的结果将如下所示:
public void foo()
{
    string str = "";

    //inner

    $endif$ //outer

    return str;
}

正如你所看到的,第一个$endif$后面的所有内容都被留在了代码中。我想到了一个适当的解决方法,涉及使用&运算符和串联if语句的组合。 有一个逻辑&运算符可以在单个if语句中使用。 语法如下:
$if$ ($foo$|$bar$ == true|false)

这将被计算为$foo$ == true && $bar$ == false。可以使用多于两个操作数,例如$foo$|$bar$|$baz$|... == true|false|etc|...。此用法的注意事项是在语句中所有比较只能使用单个运算符类型(==|!= 不可)。我无法找到任何类似于“Or”运算符的东西。
把它们全部结合起来。&运算符可以与一系列if语句一起使用,创建一个模拟的嵌套-if环境。以下示例展示了三个级别的嵌套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;
}

0

对于逻辑运算符 andor
and 是:
&&
or 是:
||

因此,一个带有 and 的 if 语句看起来像这样:

if ((a != null)&&(a !=""))
{
    Console.Write(a);
}

如果在if语句中使用or,则会像这样:

if ((b != null)||(b >= 5))
{
    Console.Write(b);
}

对于模板,您可以将 *.cs 文件导出为模板。它在“项目(Project)> 导出模板…”下方。

(我使用的是Visual Studio 2017)

希望这能帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接