Ben*_*dEg 25 .net c# string-interpolation c#-6.0
为什么c#中的字符串插值不适用于const字符串?例如:
private const string WEB_API_ROOT = "/private/WebApi/";
private const string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
Run Code Online (Sandbox Code Playgroud)
从我的角度来看,一切都在编译时就已知.或者这是一个稍后会添加的功能?
编译器消息:
分配给"DynamicWebApiBuilder.WEB_API_PROJECT"的表达式必须是常量.
非常感谢!
Ren*_*ogt 40
插值字符串只是转换为调用string.Format.所以你的上一行实际上是读
private const string WEB_API_PROJECT = string.Format("{0}project.json", WEB_API_ROOT);
Run Code Online (Sandbox Code Playgroud)
这不是编译时常量,因为包含了方法调用.
另一方面,字符串连接(简单的,常量字符串文字)可以由编译器完成,因此这将起作用:
private const string WEB_API_ROOT = "/private/WebApi/";
private const string WEB_API_PROJECT = WEB_API_ROOT + "project.json";
Run Code Online (Sandbox Code Playgroud)
或切换const到static readonly:
private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
Run Code Online (Sandbox Code Playgroud)
所以string.Format在第一次访问声明类型的任何成员时初始化(和调用)字符串.
svi*_*ick 17
字符串插值表达式不被认为是常量的另一个原因是它们不是常数,即使它们的所有输入都是常量.具体而言,它们根据当前的文化而有所不同.尝试执行以下代码:
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
Console.WriteLine($"{3.14}");
CultureInfo.CurrentCulture = new CultureInfo("cs-CZ");
Console.WriteLine($"{3.14}");
Run Code Online (Sandbox Code Playgroud)
它的输出是:
3.14
3,14
Run Code Online (Sandbox Code Playgroud)
请注意,输出是不同的,即使字符串插值表达式在两种情况下都相同.因此,const string pi = $"{3.14}"编译器生成的代码不清楚.
有在罗斯林项目的讨论 罗斯林即完成了以下结论:
阅读摘录:
这不是一个错误,它明确地设计为像这样的功能.你不喜欢它不会成为一个错误.串联字符串不需要String.Format,但这不是你正在做的事情.你正在插入它们,并且需要String.Format,这是基于插值在C#中如何工作的规范和实现.
如果要连接字符串,请继续使用与C#1.0相同的语法.根据使用情况将实现更改为不同的行为会产生意外结果:
const string FOO = "FOO";
const string BAR = "BAR";
string foobar = $"{FOO}{BAR}";
const string FOOBAR = $"{FOO}{BAR}"; // illegal today
Debug.Assert(foobar == FOOBAR); // might not always be true
Run Code Online (Sandbox Code Playgroud)
甚至声明:
private static readonly string WEB_API_PROJECT = $"{WEB_API_ROOT}project.json";
Run Code Online (Sandbox Code Playgroud)
编译器引发错误:
"The name 'WEB_API_ROOT' does not exist in the current context".
Run Code Online (Sandbox Code Playgroud)
应在同一上下文中定义变量"WEB_API_ROOT"
因此,对于OP的问题:为什么字符串插值不适用于const字符串?答:这是C#6规格.有关更多详细信息,请阅读.NET编译器平台("Roslyn") - C#的字符串插值
C# 10(在撰写本文时目前为预览版)将包括使用const内插字符串的能力,只要使用不涉及文化可能影响结果的场景(例如本示例)。
因此,如果插值只是将字符串连接在一起,它将在编译时工作。
const string Language = "C#";
const string Platform = ".NET";
const string Version = "10.0";
const string FullProductName = $"{Platform} - Language: {Language} Version: {Version}";
Run Code Online (Sandbox Code Playgroud)
如果preview选择了语言版本(<LanguageVersion>preview</LanguageVersion>在您的项目文件中设置),那么现在在 VS 2019 版本 16.9 中允许这样做。
https://github.com/dotnet/csharplang/issues/2951#issuecomment-736722760
| 归档时间: |
|
| 查看次数: |
8372 次 |
| 最近记录: |