C# 在具有反射的类中使用常量

C# 在具有反射的类中使用常量,c#,string,constants,system.reflection,C#,String,Constants,System.reflection,所以。。。请看一看这个例子: public class StatesList() { public const string State1Name = "State1"; public const string State2Name = "State2"; public const string State3Name = "State3"; } public class Test() { private currentState = StatesList.St

所以。。。请看一看这个例子:

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);
       }
    }
}
我想要实现的是能够“解析”测试类并创建一个包含所用状态名的列表。在本例中,我希望能够创建一个包含StatesList.State1Name和StatesList.State3Name的列表。是否可以使用反射,或者我实际上必须创建一个解析器(将cs文件作为文本加载)来实现它


非常感谢:-)

反射是不可能的。源代码无法通过反射获得;只有元数据。编译后,常量会被它们的文本值替换,因此即使查看类的IL,也无法判断是使用了常量还是文本字符串


解析源代码可能是您的最佳选择。

反射是不可能的。源代码无法通过反射获得;只有元数据。编译后,常量会被它们的文本值替换,因此即使查看类的IL,也无法判断是使用了常量还是文本字符串


解析源代码可能是您的最佳选择。

使用regex只需解析文件即可:

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();
}
私有静态列表GetUsedConstants(字符串路径到文件,字符串常量类)
{
var text=File.ReadAllText(路径到文件);
var rx=新正则表达式(常量class+@“\。\w+”);
返回rx.Matches(text.Cast().Select(m=>m.Value).Distinct().ToList();
}

使用regex并只解析文件:

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();
}
私有静态列表GetUsedConstants(字符串路径到文件,字符串常量类)
{
var text=File.ReadAllText(路径到文件);
var rx=新正则表达式(常量class+@“\。\w+”);
返回rx.Matches(text.Cast().Select(m=>m.Value).Distinct().ToList();
}

正如我在评论中提到的,您似乎是通过尝试实现“状态机”来实现的。这并不能直接回答你的问题,但它可以帮助你解决实际问题。状态被实现为实状态类的实际子类。这样,您就不需要任何
if
case
语句来确定要运行哪个状态的逻辑;每个子类上都有一个Execute方法,该方法有自己的特定于状态的逻辑。如果这听起来像是你感兴趣的东西,只要让我知道,我会为你做一个简单的例子

控制台应用程序中状态机的一个非常简单的示例。它在两个状态之间切换,其中一个状态从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));
            }
        }
    }
}

正如我在评论中提到的,您似乎通过尝试实现一个“状态机”来实现。这并不能直接回答你的问题,但它可以帮助你解决实际问题。状态被实现为实状态类的实际子类。这样,您就不需要任何
if
case
语句来确定要运行哪个状态的逻辑;每个子类上都有一个Execute方法,该方法有自己的特定于状态的逻辑。如果这听起来像是你感兴趣的东西,只要让我知道,我会为你做一个简单的例子

控制台应用程序中状态机的一个非常简单的示例。它在两个状态之间切换,其中一个状态从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));
            }
        }
    }
}

为什么您需要知道使用了哪些?最终目标是什么?可能有不同的方法来解决您的问题。您的状态似乎可以更好地实现为真实
状态
类的实际子类。这样,您就不需要任何
if
case
语句来确定要运行的逻辑;每个子类都有一个
Execute
方法,该方法有自己的特定于状态的逻辑。如果这听起来像是你感兴趣的东西,请告诉我,我会给你举一个简单的例子。这看起来像是一个X/Y问题。你问的是如何做X,但你真的应该放弃它而做Y。了解你试图解决的问题将有助于我们为你提供一个好的答案。为什么你需要知道使用了哪些?最终目标是什么?可能有不同的方法来解决您的问题。您的状态似乎可以更好地实现为真实
状态
类的实际子类。这样,您就不需要任何
if
case
语句来确定要运行的逻辑;每个子类都有一个
Execute
方法,该方法有自己的特定于状态的逻辑。如果这听起来像是你感兴趣的东西,请告诉我,我会给你举一个简单的例子。这看起来像是一个X/Y问题。你在问如何做X,但你真的应该放弃它而做Y。了解你试图解决的问题将有助于我们为你提供一个好的答案。您好,谢谢您的示例。其思想是创建一个一次能够执行多个行为的状态机。在每种行为中都有可能过渡到不同的状态(这将由第一次发生的条件定义)。有些行为是不同国家的共同行为。问题是,每个行为的状态都应该是公共的,并且通过定义要转换的状态的字符串,可以实现转换。获取行为中使用的状态可以让我不触发错误的转换。您好,谢谢您的示例。其思想是创建一个一次能够执行多个行为的状态机。在每种行为中都有可能过渡到不同的状态(这将由第一次发生的条件定义)。有些行为是不同国家的共同行为。问题是,每个行为的状态都应该是公共的,并且通过定义要转换的状态的字符串,可以实现转换。了解行为中使用的状态可以让我不触发错误的转换。您好,谢谢您的回答。是的,我爱你