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

时间:2017-12-02 10:06:37

标签: c# const language-lawyer

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

const string a = "A";
const string ab = a + "B";

是否有可能基于常量int创建常量字符串?例如,以下不会编译:

const int Dpi = 300;
const string DeviceInfo = "<DeviceInfo><Dpi>" + Dpi + "</Dpi></DeviceInfo>";
  

分配给MyClass.DeviceInfo的表达式必须是常量。

我知道我可以通过

解决这个问题
  1. 使Dpi成为字符串而不是int(并且当我需要int值时int.Parse
  2. 添加第二个字符串常量DpiString(因此,违反DRY)或
  3. 使DeviceInfo成为static readonly字段而非const字段。
  4. 我打算选择3,但是,出于好奇,我想知道是否还有其他一些选项让我错过了......

3 个答案:

答案 0 :(得分:4)

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

  

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

     
      
  • 身份转换
  •   
  • 数字转换
  •   
  • 枚举转化
  •   
  • 常量表达式转换
  •   
  • 隐式和显式引用转换,前提是转换源是一个计算结果为空值的常量表达式。
  •   
     

在常量表达式中不允许进行其他转换,包括装箱,取消装箱和非空值的隐式引用转换。

int转换为string属于&#34;其他转换&#34;这是不允许的,因为这需要调用ToString()方法。

事实上,转换需要调用int.ToString(),该G10被定义为使用NumberFormatInfo.NegativeSign数字格式。这取决于当前的文化\u002d,因此原则上可以改变。我不知道任何默认文化除了使用#include<experimental/type_traits> template<typename T> using iterator_t = typename T::iterator; template<typename T> constexpr bool has_iterator = std::experimental::is_detected_v<iterator_t, T>; template<class Container> int some_function(const Container& container) { if constexpr (has_iterator<Container>) { // get an element by its iterator } else { // do another action } } 连字符 - 减号字符之外还使用任何其他负号,但如果你想看世界燃烧,你肯定可以在运行时将它设置为其他东西

答案 1 :(得分:1)

你不能用const做到这一点。但你最关心的是什么?您是否希望确保该值永远不会更改,或者您希望它在编译时可用吗?

如果您想确保它永远不会改变,您可以使用以下任何一种:

  1. Readonly field
  2. 包含字段的Readonly属性,两者都封装在单例类中。
  3. 在运行时连接字符串的只读属性
  4. 静态只读字段
  5. 但在某些用例中,您可能希望在编译时获得该值。在这种情况下,你必须使你的整数成为一个const字符串,正如你在选项1和2中所描述的那样。

答案 2 :(得分:0)

有两种方法可以处理这种情况:

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

2)如果Dpi不是常数值。然后你应该尝试使用String.format