我可以通过在C#中连接字符串和int常量来创建字符串常量吗?

我可以通过在C#中连接字符串和int常量来创建字符串常量吗?,c#,constants,language-lawyer,C#,Constants,Language Lawyer,我知道我可以通过连接其他常量字符串来创建新的常量字符串: const string a = "A"; const string ab = a + "B"; 是否可以基于常量int创建常量字符串?例如,以下内容将不会编译: const int Dpi = 300; const string DeviceInfo = "<DeviceInfo><Dpi>" + Dpi + "</Dpi></DeviceInfo>"; const int Dpi=3

我知道我可以通过连接其他常量字符串来创建新的常量字符串:

const string a = "A";
const string ab = a + "B";
是否可以基于常量int创建常量字符串?例如,以下内容将不会编译:

const int Dpi = 300;
const string DeviceInfo = "<DeviceInfo><Dpi>" + Dpi + "</Dpi></DeviceInfo>";
const int Dpi=300;
常量字符串DeviceInfo=“+Dpi+”;
分配给MyClass.DeviceInfo的表达式必须是常量

我知道我可以通过

  • 使
    Dpi
    成为字符串而不是int(并且
    int.Parse
    在需要int值时对其进行解析)
  • 添加第二个字符串常量
    DpiString
    (从而违反DRY),或
  • 使
    DeviceInfo
    成为
    静态只读
    字段,而不是
    const
    字段

  • 我将使用选项3,但出于好奇,我想知道是否还有其他选项我错过了…

    不,字符串常量不能是在运行时计算的表达式

    常量表达式中允许进行以下转换:

    • 身份转换
    • 数字转换
    • 枚举转换
    • 常量表达式转换
    • 隐式和显式引用转换,前提是转换源是计算结果为空值的常量表达式
    常量表达式中不允许其他转换,包括装箱、取消装箱和非空值的隐式引用转换

    int
    转换为
    string
    属于不允许的“其他转换”,因为这需要调用
    ToString()
    方法


    事实上,转换需要调用
    int.ToString()
    ,该调用被定义为使用
    G10
    数字格式。这取决于当前区域性的
    NumberFormatInfo.NegativeSign
    ,因此原则上可以更改。我不知道有任何默认区域性使用任何负号,而不是
    \u002d
    连字符减号,但是如果您希望看到世界燃烧,您当然可以在运行时将其设置为其他值。

    有两个选项来处理此情况:

    1) 如果
    Dpi
    总是相同的(因为它是一个常数),那么就不需要对两个不同的字符串进行编码。您可以直接将值写入字符串本身


    2) 如果
    Dpi
    不是一个常量值。然后您应该尝试使用
    String.format

    您不能使用const。但你在这里最关心的是什么?您想确保该值永远不会更改,还是希望它在编译时可用

    如果要确保它永远不会更改,可以使用以下任一选项:

  • 只读字段
  • 带有字段的只读属性,两者都封装在一个单例类中
  • 运行时连接字符串的只读属性
  • 静态只读字段

  • 但是在某些用例中,您可能希望在编译时提供该值。在这种情况下,您必须将整数设置为常量字符串,如选项1和2中所述。

    当前表达式不是常量表达式,因为将int转换为字符串将使用格式提供程序,该提供程序仅在运行时可用。因此
    string+object
    object
    使用区域性敏感转换?很高兴知道,不幸的是,这一点不是很清楚。只需违反DRY,并放入一个测试用例以确保值不会失去同步。因此,本质上,您是说
    string+object
    执行
    object
    的区域性敏感转换,因此不能在编译时执行。@Heinzi,不,我是说你不能这样做,因为标准不允许这样做,因此编译器不包含使它工作所需的逻辑。所有的功能一开始都不存在——要想让它工作,就需要有人编写代码来让它工作,他们没有,所以它没有!事实上,
    int.ToString()
    被定义为使用当前区域性:但它可以有不同的定义。有趣的是-输出字符串实际上可以依赖于当前区域性-如果它是负数,则将使用当前区域性的
    NumberFormatInfo.NegativeSign
    。@Heinzi是的,这让我很惊讶!1) 2)也不起作用。您还可以尝试为设备信息创建一个模型类,稍后将其序列化为XML。