Search code examples
visual-studiomsbuildcsproj

How to specify a '|net35|net40|net45|'.Contains($(TargetFramework)) condition for an ItemGroup (*.csproj)?


I have a C# (SDK) project with multi targeting where I have to include a certain file only in some older framework versions and I can easily achieve it like this:

<ItemGroup Condition="('$(TargetFramework)'=='net35') Or ('$(TargetFramework)'=='net40') Or ('$(TargetFramework)'=='net45') Or ('$(TargetFramework)'=='net451') Or ('$(TargetFramework)'=='net452')">
  <!-- do something -->
</ItemGroup>

But that looks a bit clumsy and is not easy to read, so I tried to do it like this (and dozens of variations of it) but without any success:

<ItemGroup Condition="'|net35|net40|net403|net45|net451|net452|'.Contains('|$(TargetFramework)|')">
  <!-- do something -->
</ItemGroup>

Is there a way of doing it with a string contains operation?

I checked posts like these: Is there any MSbuild task to check if a string contains another string (similar to string.contains) but what they do there does not seem to work for me.

The version I am using is Visual Studio 2019 (16.9.4)


Solution

  • It appears that you cannot call instance string functions directly on string literals. The MSBuild documentation suggests it's only possible to call instance methods on properties.

    By moving the values you currently have inlined into a custom property, you can then use this property's Contains method like this:

        <PropertyGroup>
            <Frameworks>|net35|net40|net403|net45|net451|net452|</Frameworks>
        </PropertyGroup>
    
        <ItemGroup Condition="$(Frameworks.Contains('|$(TargetFramework)|'))">
            <!-- do something -->
        </ItemGroup>