Define enums within a method in C#?

前端 未结 5 1971
囚心锁ツ
囚心锁ツ 2020-12-18 17:50

I have mainly a C++ background and I am learning C#. So, I need some help with C# idioms and style.

I am trying to write, in C#, a small text-file parsing method i

相关标签:
5条回答
  • 2020-12-18 18:26

    I know this is old, so this is mainly for folks looking for ideas.

    The closest I can think of to creating an 'enum' type, clean structure as required, within a method is to use a dictionary.

    var stateOpt = new Dictionary<string, byte>() { { "stHeader", 0 }, { "stBody", 1 }, { "stFooter", 2 } };
    var state = stateOpt["stBody"];
    

    You can then do what you need in your condition...

    if (state == stateOpt["stHeader"] && input == ".endheader")
    {
      state = stateOpt["stBody"];
    }
    
    0 讨论(0)
  • 2020-12-18 18:27

    The closest you can get is a private nested enum with in the class:

    public class TheClass
    {
        private enum TheEnum 
        {
           stHeader, 
           stBody, 
           stFooter
        }
    
        // ...the rest of the methods properties etc... 
    }
    
    0 讨论(0)
  • 2020-12-18 18:30

    I would also favour the Enum approach. Plus, although that is not the case here, it has advantages over the CONSTS when you want to combine them as flags, since you have a method to easily test for that.

    0 讨论(0)
  • 2020-12-18 18:30

    You can't declare an enum in method scope (recapping Willem van Rumpt's answer above) but instead you can declare an inner private class to do the state-tracking and reuse it in your class methods. The containing class or its clients need not know about that auxiliary class.

    class Program
    {
        private class Parser
        {
            public string pname = "ParserPam"; 
            public enum pstate { rewind=-1, stdHeader, stBody, stFooter }
    
            public pstate state = pstate.stdHeader; 
    
            //Implement state transition logic as methods
            public void tick() => this.state = pstate.stBody;
            public void tock() => this.state = pstate.stFooter;
            public void rewind() => this.state = this.state - 1;
    
            public override string ToString()
            {
                return $"{this.pname} state: {this.state}";
            }
        }
    
        static void ParseFile(string filename)
        { 
            Parser fp = new Parser(); //This object tracks your method's state
    
            Console.WriteLine(fp); // "ParserPam state: stdHeader"
            if (fp.state == Parser.pstate.stdHeader)
            { 
                fp.tick(); // Transition
                // Do stuff
            }
    
            // Do more stuff
            Console.WriteLine(fp); // "ParserPam state: stBody"
            fp.tock();
            Console.WriteLine(fp); // "ParserPam state: stFooter"
            fp.rewind();
            Console.WriteLine(fp); // "ParserPam state: stBody"
        }
    
        static void Main(string[] args)
        {
            ParseFile( @"C:\Example" ); // Client call
        }
    }
    

    In this case, Parser is your private inner class whose instances can track state -- it is not visible outside of Program. ParseFile is a method that utilizes Parser.

    Output

    ParserPam state: stdHeader
    ParserPam state: stdBody
    ParserPam state: stFooter
    ParserPam state: stBody
    
    0 讨论(0)
  • 2020-12-18 18:48

    You can also use the constant variables but I prefer and I think is better code style to use Enums

     public class Class1
    {
        private enum TheEnum
        {
            stHeader,
            stBody,
            stFooter
        }
        public void SomeMethodEnum()
        {
            TheEnum state = TheEnum.stBody;
            switch (state)
            {
                case TheEnum.stHeader:
                    //do something
                    break;
                case TheEnum.stBody:
                    break;
                case TheEnum.stFooter:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    
    
        public void SomeMethodConst()
        {
            int state = 1;
            const int Header = 1;
            const int Body = 2;
            const int Footer = 3;
    
            switch (state)
            {
                case Header:
                    break;
                case Body:
                    break;
                case Footer:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题