Search code examples
c#.netanonymous-methods

can't reference non-static method from anonymous method


i need to call a non-static method from an async operation , for ease i'm using apm design , by defining a delegate assign it an anonymous method and calling beginInvoke on it .

to my surprise i could not reference a non-static method from my implementation

any idea why that is ?

public delegate void UpdatePlayersLogin(IServerCallback callback, Guid callback_playerId, Player player, List<IServerCallback> toRemove, ManualResetEvent handel);

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant , InstanceContextMode = InstanceContextMode.PerSession)]
public class ServerService : IServer
{

    UpdatePlayersLogin updateLogin = (callback, callback_playerId, player, toRemove, handle) =>
    {
        try
        {
            callback.PlayerChangedStatus(player);
        }
        catch (Exception)
        {
            RemovePlayer(callback, callback_playerId, toRemove);
        }
        finally
        {
            handle.Set();
        }
    };

    .
    .
    private void RemovePlayer(IServerCallback callback, Guid playerId, List<IServerCallback> toRemove)
    { . . . . . . }

    private void NotifyPeersOfClientLogin(Player player)
    {
        . . . . .   
         foreach (var key_CallBackPair in players)
         {
                handels[i] = new ManualResetEvent(false);
                updateLogin.BeginInvoke(key_CallBackPair.Value, key_CallBackPair.Key, player, toRemove, handels[i], null, null);                     
                . . . . .
         }
        ..... 
    }

is there a way i could reference the non-static method ?


Solution

  • That should be fine if the lambda expression itself is within an instance method... but if it's in a static method, then what instance do you expect RemovePlayer to be called on?

    (As an aside, update_players_login is a highly unconventional type name. UpdatePlayersLogin would be better.)

    EDIT: Okay, my guess is that you're declaring an instance variable, like this:

    class SomeClass
    {
        Action action = () => Foo();
    
        void Foo()
        {
        }
    }
    

    If that's not the case, please clarify your post, because it's missing important information at the moment.

    If that is the case, the problem is just that an instance variable initializer can't refer to this... but you can initialize it in the constructor instead:

    class SomeClass
    {
        Action action;
    
        public SomeClass()
        {
            action = () => Foo();
        }
    
        void Foo()
        {
        }
    }
    

    I would also make the field readonly unless you intend to reassign it somewhere else.