对于一个自我回归的 Func 来说,正确的'T'是什么<T>?



返回值的函数:

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 中的代码

最新更新