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。了解你试图解决的问题将有助于我们为你提供一个好的答案。您好,谢谢您的示例。其思想是创建一个一次能够执行多个行为的状态机。在每种行为中都有可能过渡到不同的状态(这将由第一次发生的条件定义)。有些行为是不同国家的共同行为。问题是,每个行为的状态都应该是公共的,并且通过定义要转换的状态的字符串,可以实现转换。获取行为中使用的状态可以让我不触发错误的转换。您好,谢谢您的示例。其思想是创建一个一次能够执行多个行为的状态机。在每种行为中都有可能过渡到不同的状态(这将由第一次发生的条件定义)。有些行为是不同国家的共同行为。问题是,每个行为的状态都应该是公共的,并且通过定义要转换的状态的字符串,可以实现转换。了解行为中使用的状态可以让我不触发错误的转换。您好,谢谢您的回答。是的,我爱你