Home > OS >  How to pass const string into function
How to pass const string into function

Time:12-25

How do I pass a const string into a method to be used in a switch statement?

Context

I currently have a program that will parse a file based on customized markers. The markers are constant for the purposes of the program, but ideally can be changed between instances of running the program. I currently have the markers hard coded. I then use them in several switch statements. That works great. However, while refactoring my code, I have been unable to replicate the behavior, because I can't pass the const string variables into the function. While I could just hard code the declaration in the method, that is not ideal nor practical for obvious reasons.

I have Tried

  1. passing the variables as a ref to the original const variables: Method(ref string keyIndicator)
  2. passing the variables with the 'in' keyword : Method(in string keyIndicator)
  3. redeclaring the variables constant based on both of the above: Method(ref string keyIndicator) and Method(in string keyIndicator) followed by : const string kIndicator = keyIndicator;

Tangent

No matter what I do, I get an error:

The expression being assigned to 'x' must be constant.

But it is constant. As a side question, why is it that I can not logically assign a constant to a variable (hear me out), such that on initialization, the const string is set for the life of the program? For example:

On program run, program asks user for their name, and then that value is stored in a constant variable.

const string hi = Console.ReadLine(); <- gives me an error.

TLDR

I need to use variables for my switch statement, which I am already doing by hardcoding a constant variable. However, I am trying to refactor my code, and move these switch statements into methods, which as best I can tell, will not allow me to pass the constant variable. I know I must be missing something, as surely do not hardcode all their switch selections, and surely they use switches in methods. So, help a floundering beginner out?

Due to Requests for Code...

Original Code (roughly, I had to jigger it a bit to emulate what it would look like in the context of my program). I'm more confused than ever, because while trying to trim down the code to place here, it actually DID work. But only in a secondary file. I copied the code back to my program, and it doesn't. >:/.

WORKING test file Created to show what I was trying to do...

    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;
                        }
                    }
                }
            }
        }
    }
}

Runs with output

Key start 21
Key end 29
body start 50
body end 58
clinical start 79
clinical end 91

While this same code :

    //
    //
    //!!!!!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;
                    }
                }
            }
        }
    }

Gives me the error that the indicators (i.e. "keyIndicator") need to be constant.

CodePudding user response:

Only literals or constants can be used in labels of switch statements. Most languages' grammars are specified in that way. If you need to switch on variables, replace your switch statement with an if-else statement.

var x = …;
var y = …;
switch (z) {
  case x: doX(); break;
  case y: doY(); break;
  default: doOther(); break;
}

becomes

var x = …;
var y = …;
if (z == x) {
  doX();
} else if (z == y) {
  doY();
} else {
  doOther();
}

CodePudding user response:

In my above code, There was one that worked, and one that didn't, despite the code being identical.

**

The solution was that one Method was nested within Main() {}. While the other was outside of it.

**

Moving the code into Main() allowed the const variables declared there to pass into the method, and the code functions as intended. I am still unsure how to pass const across namespaces or outside of main....but for the time being that was my problem. So to all those, like myself, who like to use switch statements with non-literal cases....There ya go.

I await the knowledge and further clarification to follow :).

  • Related