简体   繁体   中英

C# How do I invoke an Action on a non-static member function?

I have the following code which works. I pass in Actions which are just pointers to static memebers of this same class. (Its purpose is to manage threading to safely access some COM objects on the rightly moded thread.)

But now I want to change DoCompute to non-static, and I want to Invoke func (also changed to non-static) with the same object that DoCompute has.

How do I get the static out, so there's passed-in data to work on?

 public static void DoCompute(Action func)
    {
      Type type = typeof(Computations);
      AppDomain interopDomain = null;
      if (thread != null)
        thread.Join();
      try
      {
          // Define thread.
          thread = new System.Threading.Thread(() =>
          {
              // Thread specific try\catch.
              try
              {
                  // Create a custom AppDomain to do COM Interop.
                string comp = "Computations";
                  interopDomain = AppDomain.CreateDomain(comp);

    //// THIS LINE:  What if func is a non-static member?
                  func.Invoke();

                  Console.WriteLine();
                  Console.WriteLine("End ");
              }
              catch (System.Exception ex)
              {
                  Console.WriteLine(ex.Message);
              }
          });

          // Important! Set thread apartment state to STA.
          thread.SetApartmentState(System.Threading.ApartmentState.STA);

          // Start the thread.
          thread.Start();

          // Wait for the thead to finish.
          thread.Join();
      }
      catch (System.Exception ex)
      {
          Console.WriteLine(ex.Message);
      }
      finally
      {
          if (interopDomain != null)
          {
              // Unload the Interop AppDomain. This will automatically free up any COM references.
              AppDomain.Unload(interopDomain);
          }
      }
  }

You just remove the static keywords from both. Under the hood, when you pass an instance method into the Action parameter, the instance is passed along as an invisible first parameter. If you pass a static method into the Action parameter, that does not happen. The only thing you cannot do is pass a non-static method into the paramater from a static method.

Perhaps this will be clearer with some code:

public class TestClass
{
    private string _text;

    private void DoCompute(Action func)
    {
        func.Invoke();
    }

    private static void DoComputeStatic(Action func)
    {
        func.Invoke();
    }

    private static void StaticFunc()
    {
        Console.WriteLine("Static func");
    }

    private void NonstaticFunc()
    {
        Console.WriteLine(_text);
    }

    public void Run()
    {
        _text = "Nonstatic func";
        DoCompute(NonstaticFunc);
        DoComputeStatic(StaticFunc); //Can use static method - instance is ignored
    }

    public static void RunStatic()
    {
        DoComputeStatic(StaticFunc);
        //DoCompute(NonstaticFunc);  // Cannot use instance method - no instance
    }

    public void RunWithThread()
    {
        Thread thread = new Thread(() =>
        {
            _text = "Nonstatic func";
            DoCompute(NonstaticFunc);
        });
        thread.Start();
        thread.Join();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM