所以......请看一下这个例子:
public class StatesList() {
public const string State1Name = "State1";
public const string State2Name = "State2";
public const string State3Name = "State3";
}
public class Test() {
private currentState = StatesList.State1Name;
public static void Main(string[] args) {
while(true) {
if(currentState == StatesList.State1Name) {
State1();
} else if (currentState == StatesList.State3Name) {
State2();
}
}
}
public void ChangeState(string newState) {
currentState = newState;
}
public void State1() {
// do stuff.
if(iAmSilly) {
ChangeState(StatesList.State3Name);
}
}
public void State2() {
// do stuff.
if(!iAmSilly) {
ChangeState(StatesList.State1Name);
}
}
}
我想要实现的是能够“解析”Test类并使用使用的状态名创建一个列表。在该示例中,我希望能够创建包含StatesList.State1Name和StatesList.State3Name的列表。是否可以使用反射或者我是否真的必须创建一个解析器(将cs文件作为文本加载)来实现它?
非常感谢: - )
答案 0 :(得分:4)
反射是不可能的。源代码不能通过反射获得;只有元数据。并且在编译之后常量被它们的字面值替换,所以即使你查看类的IL,你也无法判断是否使用了常量或文字字符串。
解析源代码可能是您的最佳选择。
答案 1 :(得分:1)
使用正则表达式并解析文件:
private static List<string> GetUsedConstants(string path_to_file, string const_class)
{
var text = File.ReadAllText(path_to_file);
var rx = new Regex(const_class + @"\.\w+");
return rx.Matches(text).Cast<Match>().Select(m => m.Value).Distinct().ToList();
}
答案 2 :(得分:0)
正如我在评论中提到的,你似乎试图实现一个&#34;状态机&#34;。这并不能直接回答您的问题,但它可以帮助您解决实际问题。状态被实现为真实State类的实际子类。这样,您就不需要任何if
或case
语句来确定要运行哪个州的逻辑;每个子类都有一个Execute方法,它有自己的特定于状态的逻辑。如果这听起来像你感兴趣的东西,请告诉我,我会为你做一个简单的例子。
控制台应用程序中状态机的一个非常简单的示例。它在2个状态之间切换,其中一个状态从1到5计数,第二个状态从1到10计数。
using System;
namespace StateMachineExample
{
class Program
{
static void Main(string[] args)
{
SimpleStateMachine sm = new SimpleStateMachine();
sm.ChangeState(new State1(sm));
sm.Run();
}
}
class SimpleStateMachine
{
private State _currentState;
public void Run()
{
while (true)
{
_currentState.Execute();
}
}
public void ChangeState(State newState)
{
Console.WriteLine($"Changing state to: {newState.GetType()}");
_currentState = newState;
}
}
abstract class State
{
public State(SimpleStateMachine sm)
{
StateMachine = sm;
}
protected SimpleStateMachine StateMachine { get; }
public abstract void Execute();
}
class State1 : State
{
public State1(SimpleStateMachine sm) : base(sm) { }
private int _num = 0;
public override void Execute()
{
_num = _num + 1;
Console.WriteLine(_num);
if (_num > 10)
{
StateMachine.ChangeState(new State2(StateMachine));
}
}
}
class State2 : State
{
public State2(SimpleStateMachine sm) : base(sm) { }
private int _num = 0;
public override void Execute()
{
_num = _num + 1;
Console.WriteLine(_num);
if (_num > 5)
{
StateMachine.ChangeState(new State1(StateMachine));
}
}
}
}