我正在尝试理解代码,但我无法理解'p'var是什么。
public Prediction(Game kkk,bool checkit, params State[] checkStates)
: base(game, p => Manager.method(kkk, p))
{
this.checkit = checkit;
this.checkStates = checkStates;
}
第二节课:
public PiratePrediction(Game game, System.Func<Pirate, T> valueExtractor)
{
this.game = game;
this.valueExtractor = valueExtractor;
this.predictedValues = new Dictionary<Pirate, T>();
this.totalPredictions = 0;
this.correctPredictions = 0;
}
答案 0 :(得分:1)
valueExtractor
lambda来自Update
,p
来自predictedValues
字典的键。
public virtual void Update()
{
foreach (var pair in this.predictedValues)
{
if (pair.Key.State != PirateState.Lost && !EqualityComparer<T>.Default.Equals(pair.Value, default(T)))
{
this.totalPredictions++;
if (this.valueExtractor(pair.Key).Equals(pair.Value))
this.correctPredictions++;
}
}
this.predictedValues.Clear();
}
p
来自对PiratePrediction类的Predict
方法的调用。因为它已添加到predictedValues
数组中。
public T Predict(Pirate p)
{
if (this.predictedValues.ContainsKey(p))
return this.predictedValues[p];
T predictedValue = this.predict(p);
if (EqualityComparer<T>.Default.Equals(predictedValue, default(T)))
return default(T);
this.predictedValues.Add(p, predictedValue);
return predictedValue;
}
答案 1 :(得分:0)
p
是传递给方法的参数。 Func<T, TOut>
是delegate
,表示方法签名。
请考虑以下事项:
private class DisplayClass
{
public readonly Game kkk;
public DisplayyClass(Game kkk) { this.kkk = kkk; }
public T handler(Pirate p) { return Manager.method(kkk, p); }
}
public Prediction(Game kkk,bool checkit, params State[] checkStates)
: base(game, new DisplayClass(kkk).handler)
{
this.checkit= checkit;
this.checkStates = checkStates;
}
这是编译器在解释lambda时对代码所做的事情 - 将代码传递给反编译器以查看确切的措辞可能是个好主意。
正如您在扩展代码中看到的那样,p
变量是方法的参数,lambdas只是传递方法的简便方法,然后可以在其他代码中调用这些方法。
// Somewhere in the base class...
void ExtractValue(Pirate p)
{
// ...
T value = this.valueExtractor(p);
// ...
}
如果这样调用,p
将是该其他代码传入的值,并且根据Func<Pirate, T>
的定义,将为Pirate
类型。
请记住,您传递lambda的代码可以多次调用lambda中的代码,例如.Select
。我建议不仅要阅读lambdas,还要在Linq
namespace
答案 2 :(得分:0)
lambda表达式是匿名方法的声明。所以想象一下:
p => Manager.method(kkk, p)
等于:
private T SomeMethod<T>(Pirate p)
{
return Manager.method(kkk, p);
}
但是,在您的情况下,您将无法执行第二个片段,因为kkk
是声明lambda表达式的范围内的局部变量,这意味着虽然lambda可以使用{ {1}},显式方法声明不能(参见Closure)。这只是lambdas优于声明方法的一个好处。