AssemblyInfo.cs 中的模板化值?或者引用 AssemblyInfo.cs 中的其他值?

Templatized values in AssemblyInfo.cs? Or referring to other values from AssemblyInfo.cs?

我有几个 C# 项目,它们在某种意义上是一个单元。有几个常见的 AssemblyInfo 属性可以在它们之间共享(例如公司名称)。所以我做了一个所有项目都包含的共享文件,包含(例如)AssemblyCompany:

[assembly: AssemblyCompany("Acme Inc.")]

并且我从每个项目的个体AssemblyInfo.cs中删除了相应的属性。

这一切都很好,但我想在一个案例中更进一步:版权。出版的第一年因项目而异,因此它们确实应该有不同的版权字符串。所以我想在共享文件中做这样的事情:

[assembly: AssemblyCopyright(string.Format("Copyright {[=13=]} Acme Inc.", Acme.AssemblyInfo.FirstPublicationYear)]

然后让每个单独的项目定义自己特定的 Acme.AssemblyInfo.FirstPublicationYear

我在黑暗中拍了几张不同的照片。首先,我只是尝试在项目的 AssemblyInfo.cs:

中的静态 class 中定义一个 const
namespace Acme
{
    public static class AssemblyInfo
    {
        public const int FirstPublicationYear = 2015;
    }
}

这会导致错误 "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type"。所以我尝试制作一个属性 class:

namespace Acme
{
    using System;

    [AttributeUsage(AttributeTargets.Assembly)]
    public class FirstPublicationYearAttribute : Attribute
    {
        private int year;

        public FirstPublicationYearAttribute(int year)
        {
            this.year = year;
        }
    }
}

将该属性添加到单个项目的 AssemblyInfo.cs:

[assembly: Acme.FirstPublicationYear(2015)]

但我不确定如何(或者即使我可以)适当地更改共享属性文件中的 AssemblyCopyright 行。我尝试了几种没有用的方法。第一:

[assembly: AssemblyCopyright(string.Format("Copyright © {[=17=]} Acme, Inc.", Acme.FirstPublicationYear))]

... 这告诉我 FirstPublicationYear 不存在于命名空间 Acme 中。所以我想也许我会让它看起来更像一个属性:

[assembly: AssemblyCopyright(string.Format("Copyright © {[=18=]} Acme, Inc.", [assembly: Acme.FirstPublicationYear]))]

... 这告诉我 "Invalid expression term '['".

有什么方法可以完成我在这里要做的事情吗?谢谢。

而不是使用 string.Format,只需尝试连接它:

"Copyright" + Acme.AssemblyInfo.FirstPublicationYear + "Acme Inc."

编译器将能够由此生成编译时间常量。

没有很好的方法来完成这个使用代码。原因是属性 必须 具有编译时值才能将数据正确输出到结果文件,因此无法从逻辑上从部分构建它们,因为构建是根据定义a 运行-时间,不是编译时,操作。

编辑: 结果证明可以使用 + 运算符连接字符串,即使在编译时也是如此,只要连接的所有字符串都是它们自己持续的。请参阅弗兰克的回答。

但是,因为所有这些值都来自一个单个共享文件,所以可以通过编写预构建批处理文件来完成此操作.就生产代码而言,我已经将其实现为预构建步骤中的一个简单调用,其中所说的帮助程序是用 C# 编写的。只要 output 文件(通常是 AssemblyInfo.cs)被你的 repo 忽略(如果你没有使用 repo,切换到一个)你就可以依赖于由预构建生成的文件,然后由编译器找到,即使它实际上并没有被复制下来。