返回值的函数:
public object ReturnValue() { return new object(); }
Func<object> funcReturnValue = ReturnValue;
重新运行返回值的函数的函数:
public Func<object> ReturnFunc() { return ReturnValue; }
Func<Func<object>> funcReturnFunc = ReturnFunc;
到目前为止,一切都很好。我遇到了一个返回自身的函数的问题:
public *something* ReturnSelf() { return ReturnSelf; }
Func<*something*> funcReturnSelf = ReturnSelf;
很明显,*something*
将是某种类型的Func<T>
,但我不确定是什么。乍一看,我猜它将是无限递归的,因为ReturnSelf
返回一个函数,该函数返回一个返回函数的函数。。。
上下文:使用函数表示状态的状态机。它可以很好地使用保持当前状态的类变量:
private Action _currentState;
private void StateOne() {
if (IsTuesday) {
_currentState = StateTwo;
}
}
prvivate void StateTwo() {
if (IsRaining) {
_currentState = StateOne;
}
}
private void StateEngine() {
while (true) {
_currentState();
// set tuesday/raining/etc.
}
}
但这感觉太像是在全球范围内保持状态了。我更喜欢更接近的东西
private Func<*somthing*> StateOne() {
if (IsTuesday) {
return StateTwo;
} else {
return StateOne;
}
}
prvivate Func<*something*> StateTwo() {
if (IsRaining) {
return StateOne;
} else {
return StateTwo;
}
}
private void StateEngine() {
Func<*something*> currentState = StateOne;
while (true) {
Func<*something*> nextState = currentState();
// set tuesday/raining/etc.
currentState = nextState;
}
}
有什么想法吗?还是我应该坚持使用有效的解决方案?
您可以定义一个返回delegate
类型值的delegate
,而不是使用Func<T>
。委托可以用于将函数引用作为参数传递给另一个函数,或者在本例中用于从函数(docs(返回函数引用。
示例:
class Program
{
private delegate StateDelegate StateDelegate();
public static void Main(string[] args)
{
Program program = new Program();
StateDelegate stateHandler = program.HandleStateOne;
// Execute HandleStateOne, returns HandleStateTwo
stateHandler = stateHandler.Invoke();
// Execute HandleStateTwo, returns reference to HandleStateOne
stateHandler = stateHandler.Invoke();
}
private StateDelegate HandleStateOne()
{
// Do something state specific...
return HandleStateTwo;
}
private StateDelegate HandleStateTwo()
{
// Do something state specific...
return HandleStateOne;
}
// Literally return reference to the function itself
private StateDelegate ReturnSelf()
{
return ReturnSelf;
}
}
您可以在一个额外类型的帮助下完成此操作:
class State
{
private Func<State> _func;
public State(Func<State> func)
{
_func = func;
}
public State Invoke() => _func();
}
然后你可以写:
bool IsTuesday = false;
bool IsRaining = false;
State StateOne = null;
State StateTwo = null;
StateOne = new State
(
() =>
{
if (IsTuesday) {
return StateTwo;
} else {
return StateOne;
}
}
);
StateTwo = new State
(
() =>
{
if (IsRaining) {
return StateOne;
} else {
return StateTwo;
}
}
);
当然还有:
void StateEngine() {
State currentState = StateOne;
while (true) {
var nextState = currentState.Invoke();
// set tuesday/raining/etc.
currentState = nextState;
}
}
我们可以做更多的工作,隐式转换为Func<State>
(然后你就不需要invoke
方法了(:
public static implicit operator Func<State> (State state)
{
return state._func;
}
然后你可以写:
void StateEngine() {
Func<State> currentState = StateOne;
while (true) {
Func<State> nextState = currentState();
// set tuesday/raining/etc.
currentState = nextState;
}
}
因此,Func<State>
返回一些可以隐式转换为Func<State>
的内容。
SharpLap 中的代码