-1

I'm trying to understand a code but I can't understand what 'p' var is.

public Prediction(Game kkk,bool checkit, params State[] checkStates)
    : base(game, p => Manager.method(kkk, p))
{
    this.checkit = checkit;
    this.checkStates = checkStates;
}

The second class:

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;
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Sagi
  • 127
  • 2
  • 9
  • 1
    It's the parameter that is passed into the anonymous method. – Abion47 Feb 04 '17 at 21:32
  • 1
    See [SO Whats the point of a lambda expression](http://stackoverflow.com/questions/5873603/whats-the-point-of-a-lambda-expression) – Kalten Feb 04 '17 at 21:33
  • 1
    Nor do we since you did not post the constructor of the base class that is called. – Peter Bons Feb 04 '17 at 21:33
  • @Abion47 how can I detect the anonymous method? – Sagi Feb 04 '17 at 21:33
  • 1
    @Sagi Define "detect". – Abion47 Feb 04 '17 at 21:34
  • @Abion47 How can I understand what is the anonymous function? I mean like, in this class there are about 5 different methods. – Sagi Feb 04 '17 at 21:36
  • P is of type Pirate. Search for usage of valueExtractor in PiratePrediction class – Kalten Feb 04 '17 at 21:36
  • @kalten yeah, but which pirate is that? ( I mean like which object reference is that) – Sagi Feb 04 '17 at 21:36
  • See declaration of `Manager.method()` the second argument has the type of `p` which you're looking for. – Mobigital Feb 04 '17 at 21:37
  • @Sagi `p => Manager.method(kkk, p)` is the anonymous method. It's a method which takes `p` as a parameter and calls `Manager.method(kkk, p)`. So when some code actually ends up calling it, *that* is when you have a specific value for `p` to think about. –  Feb 04 '17 at 21:37
  • @Sagi It's not any specific "pirate". It's an anonymous method that you call, and when you call it, you pass a `Pirate` object as a parameter. Also, do you know what an anonymous method is? – Abion47 Feb 04 '17 at 21:38
  • @Mobigital Yeah, I know the kind of p, Im trying to understand which object is it. I mean like -> the specific object – Sagi Feb 04 '17 at 21:38
  • @Abion47 No, I don't know – Sagi Feb 04 '17 at 21:39
  • @sagi the object is not yet known, because you are dealing with only a `Lambda` body here, this `base` constructor expects to receive the `runnable function` which lambda represents. and then it will call it at some other time with actual `p` value. you can look at the code of the base constructor and see when it calls the handle it receives on 2nd argument. the 2nd argument to that function will be your `p`. don't forget to upvote. – Mobigital Feb 04 '17 at 21:40
  • Can you add some code usage of the `valueExtractor` property ? – Kalten Feb 04 '17 at 21:40
  • @Sagi I'm assigning you some required reading: https://msdn.microsoft.com/en-us/library/bb397687.aspx – Abion47 Feb 04 '17 at 21:41
  • @katlen private System.Func valueExtractor; -> type – Sagi Feb 04 '17 at 21:43
  • @Mobigital he should receive a parameter with the name 'p'? -> then it will call it? – Sagi Feb 04 '17 at 21:44
  • @Sagi, look for usages of `valueExtractor` in `PiratePrediction` class. There should be call like `somevar = valueExtractor(..., vvv)` where `vvv` is your `p` you're looking for. Maybe post the entire `PiratePrediction` class in the edit. Although this lambda could be used pretty much anywhere in your program. So origin of actual `p` parameter could be in another class as well, as long as it has access to `valueExtractor` lambda. – Mobigital Feb 04 '17 at 21:45

3 Answers3

1

found the class you're using on https://github.com/YoavKa/Skillz2016/blob/f23d25eed4baa9786cf517583ee867075a2f0505/API/Prediction/PiratePrediction.cs

the valueExtractor lambda is used from Update, and p comes from the keys of predictedValues dictionary.

 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();
    }

the p comes from the call to Predict method of PiratePrediction class. Because it's added to the predictedValues array.

    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;
    }
Mobigital
  • 749
  • 7
  • 14
0

p is a parameter being passed into your method. A Func<T, TOut> is a delegate, meaning a method signature.

Consider the following:

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;
}

This is what the compiler does to your code when interpreting lambdas - it may be a good idea to pass your code through a decompiler to see the exact phrasing.

The p variable, as you can see in the expanded code, is a parameter into the method, and lambdas are just a shorthand way to pass methods which can then be invoked in other code.

// Somewhere in the base class...
void ExtractValue(Pirate p)
{ 
    // ...
    T value = this.valueExtractor(p);
    // ...
}

When thus invoked, p will be the value passed in by that other code, and by definition of Func<Pirate, T>, will be of type Pirate.

Keep in mind that the code you're passing a lambda to can invoke the code inside your lambda multiple times, such as is the case with .Select. I suggest not only reading up on lambdas, but also their extensive use in the Linq namespace

David
  • 10,458
  • 1
  • 28
  • 40
0

A lambda expression is a declaration of an anonymous method. So imagine that this:

p => Manager.method(kkk, p)

is equal to this:

private T SomeMethod<T>(Pirate p)
{
    return Manager.method(kkk, p);
}

You wouldn't be able to do the second snippet in your situation, however, because kkk is a local variable from the scope of where the lambda expression was declared, which means that while the lambda can use kkk, an explicit method declaration can't (See Closure). This is just one benefit of lambdas over declared methods.

Abion47
  • 22,211
  • 4
  • 65
  • 88