'Build' is a special built-in target, so doesn't really work the same way as most other targets. It definitely can't be safely overridden.
The most relevant documentation is here: https://msdn.microsoft.com/en-us/library/ms366724.aspx
If you want something to run before build, the standard approach (as recommend by the comments in a newly-created .csproj file) is to override the BeforeBuild target (as documented above).
However, this isn't the most robust solution. As noted in the documentation above:
Overriding predefined targets is an easy way to extend the build process, but, because MSBuild evaluates the definition of targets sequentially, there is no way to prevent another project that imports your project from overriding the targets you already have overridden.
It's better (and only slightly more complex), to override the BuildDependsOn property and extend the default value of this property to include the target you want to run (this is also documented in the link above).
Another approach would be to leave BeforeBuild empty and use BeforeTargets="BeforeBuild"
, which feels a bit odd but is quite simple and will still work even if the BeforeBuild target gets overridden.
As to why BeforeTargets="Build"
doesn't work, I can't find a reference for this in the documentation, but I think it's to do with its special nature. It doesn't work the same as ordinary targets and it's probably better not to think of it as a target at all.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…