【发布时间】:2022-01-25 04:10:43
【问题描述】:
如何将 const 字符串传递给要在 switch 语句中使用的方法?
上下文
我目前有一个程序可以根据自定义标记解析文件。出于程序的目的,标记是恒定的,但理想情况下可以在运行程序的实例之间更改。我目前对标记进行了硬编码。然后我在几个 switch 语句中使用它们。这很好用。但是,在重构我的代码时,我无法复制该行为,因为我无法将 const 字符串变量传递给函数。虽然我可以在方法中对声明进行硬编码,但由于显而易见的原因,这既不理想也不实用。
我试过了
- 将变量作为 ref 传递给原始 const 变量:
Method(ref string keyIndicator) - 使用“in”关键字传递变量:
Method(in string keyIndicator) - 基于以上两个重新声明变量常量:
Method(ref string keyIndicator)和Method(in string keyIndicator)后跟:const string kIndicator = keyIndicator;
切线
无论我做什么,我都会得到一个错误:
分配给“x”的表达式必须是常量。
但它是不变的。 作为一个附带问题,为什么我不能在逻辑上将一个常量分配给一个变量(听我说),这样在初始化时,常量字符串就被设置为程序的生命周期?例如:
在程序运行时,程序会询问用户的姓名,然后将该值存储在一个常量变量中。
const string hi = Console.ReadLine();
TLDR
我需要为我的 switch 语句使用变量,我已经通过硬编码一个常量变量来做到这一点。但是,我正在尝试重构我的代码,并将这些 switch 语句移动到方法中,据我所知,这将不允许我传递常量变量。我知道我一定遗漏了一些东西,因为肯定不会对他们所有的开关选择进行硬编码,而且他们肯定会在方法中使用开关。那么,帮助一个陷入困境的初学者吗?
由于请求代码...
原始代码(粗略地说,我不得不稍微调整一下以模拟它在我的程序上下文中的样子)。我比以往任何时候都更加困惑,因为在尝试缩减代码以放置在这里时,它实际上确实有效。但仅在辅助文件中。我将代码复制回我的程序,但它没有。 >:/.
工作测试文件创建以显示我正在尝试做的事情...
internal class Program{
static void Main(string[] args)
{
string fileToParse = "!--------------------Demo Key@--------------------DemoBody#--------------------DemoClinical";
//
//
//!!!!!Set Constants for Deliniators!!!!
//
//
const string divider = "--------------------";
const string keySign = "!";
const string bodySign = "@";
const string clinicalSign = "#";
//
//
//!!!!!Set Constants for Deliniators!!!!
//
//
const string keyIndicator = keySign + divider;
const string bodyIndicator = bodySign + divider;
const string clinicalIndicator = clinicalSign + divider;
//
//
List<String> checkDeliniators = new List<String>();
checkDeliniators.Add(keyIndicator);
checkDeliniators.Add(bodyIndicator);
checkDeliniators.Add(clinicalIndicator);
SetIndexes(ref fileToParse, checkDeliniators);
static void SetIndexes(ref string fileToParse, List<string> checkDeliniators)
{
//Create Lists of indexes (Starts and Stops for Text desired)
foreach (var indicator in checkDeliniators)
{
int index = 0;
while ((fileToParse.IndexOf(indicator, index)) != -1)
{
index = fileToParse.IndexOf(indicator, index); // (Undesired text"!"------Desired text)
index = index + indicator.Length; // (Undesired text!-------""Desired text)
//assigns this index to the appropriate list
switch (indicator)
{
case keyIndicator:
Console.WriteLine("Key start {0}", index);
break;
case bodyIndicator:
Console.WriteLine("body start {0}", index);
break;
case clinicalIndicator:
Console.WriteLine("clinical start {0}", index);
break;
default:
// Do this;
break;
}
//sets END of Text
if ((fileToParse.IndexOf(divider, index)) != -1) //(if there are more instances of divider, move index forward)
{
//indexed moved forward to next divider, and then backed up to desired text END.
index = fileToParse.IndexOf(divider, index); // (!"-"------) (diver used because next Indicator not predictable)
index = index - keySign.Length; // ("!"-------) (Recall end index is not inclusive)
switch (indicator) //refers to prior indicator (end), not next indicator (start)
{
case keyIndicator:
Console.WriteLine("Key end {0}", index);
break;
case bodyIndicator:
Console.WriteLine("body end {0}", index);
break;
case clinicalIndicator:
Console.WriteLine("clinical end {0}", index);
break;
default:
// Do this;
break;
}
index++; // (!"-"-------) Technically shouldn't be necessary, but just incase search for divider in future...
}
else //else, if there are no more instances of divider, leave the index alone, and set the end of text to end of file
{
index = fileToParse.Length;
switch (indicator)
{
case keyIndicator:
Console.WriteLine("Key end {0}", index);
break;
case bodyIndicator:
Console.WriteLine("body end {0}", index);
break;
case clinicalIndicator:
Console.WriteLine("clinical end {0}", index);
break;
default:
// Do that;
break;
}
}
}
}
}
}
}
带输出运行
Key start 21
Key end 29
body start 50
body end 58
clinical start 79
clinical end 91
虽然代码相同:
//
//
//!!!!!Set Constants for Deliniators!!!!
//
//
const string divider = "--------------------";
const string keySign = "!";
const string bodySign = "@";
const string clinicalSign = "#";
//
//
//!!!!!Set Constants for Deliniators!!!!
//
//
const string keyIndicator = keySign + divider;
const string bodyIndicator = bodySign + divider;
const string clinicalIndicator = clinicalSign + divider;
//
//
List<String> checkDeliniators = new List<String>();
checkDeliniators.Add(keyIndicator);
checkDeliniators.Add(bodyIndicator);
checkDeliniators.Add(clinicalIndicator);
List<String> KeyList = new List<String>();
List<String> BodyList = new List<String>();
List<String> ClinicalList = new List<String>();
List<String> GarbageList = new List<String>();
List<int> keyStartIndex = new List<int>();
List<int> bodyStartIndex = new List<int>();
List<int> clinicalStartIndex = new List<int>();
List<int> garbageStartIndex = new List<int>();
List<int> keyEndIndex = new List<int>();
List<int> bodyEndIndex = new List<int>();
List<int> clinicalEndIndex = new List<int>();
List<int> garbageEndIndex = new List<int>();
const string fileSign = "|";
//const string commentSign = "~";
//const string allIndicators = keySign + bodySign + clinicalSign;
string fileStartIndicator = fileSign + divider;
string fileEndIndicator = divider + fileSign;
bool headerSet = SetHeader(ref fileToParse, fileStartIndicator, ref fileHeader);
bool footerSet = SetFooter(ref fileToParse, fileEndIndicator, ref fileFooter);
SetIndexes(ref fileToParse, checkDeliniators);
static void SetIndexes(ref string fileToParse, List<string> checkDeliniators)
{
//Create Lists of indexes (Starts and Stops for Text desired)
foreach (var indicator in checkDeliniators)
{
int index = 0;
while ((fileToParse.IndexOf(indicator, index)) != -1)
{
index = fileToParse.IndexOf(indicator, index); // (Undesired text"!"------Desired text)
index = index + indicator.Length; // (Undesired text!-------""Desired text)
//assigns this index to the appropriate list
switch (indicator)
{
case keyIndicator:
keyStartIndex.Add(index);
break;
case bodyIndicator:
bodyStartIndex.Add(index);
break;
case clinicalIndicator:
clinicalStartIndex.Add(index);
break;
default:
garbageStartIndex.Add(index);
break;
}
//sets END of Text
if ((fileToParse.IndexOf(divider, index)) != -1) //(if there are more instances of divider, move index forward)
{
//indexed moved forward to next divider, and then backed up to desired text END.
index = fileToParse.IndexOf(divider, index); // (!"-"------) (diver used because next Indicator not predictable)
index = index - keySign.Length; // ("!"-------) (Recall end index is not inclusive)
switch (indicator) //refers to prior indicator (end), not next indicator (start)
{
case keyIndicator:
keyEndIndex.Add(index);
break;
case bodyIndicator:
bodyEndIndex.Add(index);
break;
case clinicalIndicator:
clinicalEndIndex.Add(index);
break;
default:
garbageEndIndex.Add(index);
break;
}
index++; // (!"-"-------) Technically shouldn't be necessary, but just incase search for divider in future...
}
else //else, if there are no more instances of divider, leave the index alone, and set the end of text to end of file
{
index = fileToParse.Length;
switch (indicator)
{
case keyIndicator:
keyEndIndex.Add(index);
break;
case bodyIndicator:
bodyEndIndex.Add(index);
break;
case clinicalIndicator:
clinicalEndIndex.Add(index);
break;
default:
garbageEndIndex.Add(index);
break;
}
}
}
}
}
告诉我指标(即“keyIndicator”)需要保持不变的错误。
【问题讨论】:
-
tldr;写代码,或者分享你写的代码。
-
ReadLine不返回常量。它每次返回不同的值。 -
根据定义,常量是在程序编译时确定的。它不能是程序运行时确定的任何东西。如果您有一个字符串,但它可能是一个字符串或可能是不同的字符串,它必须是一个变量。它是变化的,所以它是一个变量。
-
您似乎认为 C# 中的
const与 C++ 中的const一样。它不是。 C# 中的readonly更接近于 C++const。 C# 中的const类似于 C++#define或constexpr。 -
为什么不能使用对编译时间常数没有任何限制的
if()?
标签: c# switch-statement constants