问题
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 in which I need a simple state variable with three states. In C++ I would declare an enum like this for the state variable:
enum { stHeader, stBody, stFooter} state = stBody;
...and then use it in my parsing loop like this:
if (state == stHeader && input == ".endheader")
{
state = stBody;
}
In C# I realize that it is not possible to declare an enum inside a method. So, what I am supposed to do for sake of clean style? Declare this internal enum outside of the method? Use magic numbers 1,2,3? Create a separate class for this?
Please help me clear up my confusion.
回答1:
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...
}
回答2:
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();
}
}
}
回答3:
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.
回答4:
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
来源:https://stackoverflow.com/questions/5603910/define-enums-within-a-method-in-c