【问题标题】:C# pass methods as parametersC#将方法作为参数传递
【发布时间】:2018-09-09 09:47:38
【问题描述】:

我正在使用 C# 中的 C API。在 C 中方法作为参数传递,我试图在 C# 中完成同样的事情。

C 中,我会按以下方式调用函数:

 LL_SetStatusCb(OnStatusRcv);
 LL_SetScanCb(scanCb);
 LL_Scan();

请注意,使用的方法是按以下方式定义的:

void OnStatusRcv(ll_status_t status)
void scanCb(ll_scan_result_t *result)

在 C# 中,方法的定义方式相同,但我不知道如何传递这些方法。

【问题讨论】:

标签: c# c++ c api pointers


【解决方案1】:

函数指针的 C# 等价物是委托。您可以使用 Func 和 Action 将方法作为参数传递。 Func委托代表接受N个参数并返回值的方法,Action委托代表void方法。

考虑一下

void (* myFunction)(int parameter) 

在 C# 中是

Action<int> 

【讨论】:

    【解决方案2】:

    请试试这个代码:

    创建 ll_scan_result_t 和 ll_status_t 类。

    class Program
    {
        delegate void ActionRef<T>(ref T item);
    
        static void Main(string[] args)
        {
            ll_status_t _status = new ll_status_t();
    
            LL_SetStatusCb(_status, OnStatusRcv);
    
            ll_scan_result_t _scan = new ll_scan_result_t();
    
            LL_SetScanCb(ref _scan);
        }
    
        static void LL_SetScanCb(ref ll_scan_result_t status, ActionRef<ll_scan_result_t> getCachedValue)
        {
            //... do something
        }
    
        static void LL_SetStatusCb(ll_status_t result, Action<ll_status_t> getCachedValue)
        {
            //... do something
        }
    
        static void OnStatusRcv(ref ll_scan_result_t sresult)
        {
            //... do something
        }
    
        static void scanCb(ll_status_t s)
        {
            //... do something
        }
    }
    

    【讨论】:

      【解决方案3】:

      使用下面的 Func 委托

      public class myClass
      {
      
          public bool TestMethod(string input)
          {
              return true;
          }
          public bool Method1(Func<string, bool> methodName)
          {
              return true;
          }
      
          public void newMthod()
          {
              Method1(TestMethod);
          }
      }
      

      【讨论】:

        【解决方案4】:

        在 C# 中,与 C/C++ 等效的函数指针委托。委托是一种表示对具有特定参数列表和返回类型的方法的引用的类型。实例化委托时,可以将其实例与具有兼容签名和返回类型的任何方法相关联。您可以通过委托实例调用该方法。

        这是一个例子。首先,声明一个委托:

        public delegate void Del(string message);
        

        现在,Del 是一个委托类型,可用于调用任何返回 void 并接受 string 类型参数的方法。现在,让我们创建一些匹配Del的签名和返回类型的方法:

        public static void DelegateMethod(string message)
        {
            Console.WriteLine(message);
        }
        

        现在,让我们创建一个Del 的实例并将其与DelegateMethod 关联,如下所示:

        Del handler = DelegateMethod;
        

        如果您想拨打DelegateMethod,您可以通过以下方式进行:

        handler("Hello World");
        

        请注意,由于Del 是一种类型,您可以执行以下操作:

        public static void SomeMethod(Del callback, string callbackParams)
        {
            callback(callbackParams);
        }
        

        可以用作:

        SomeMethod(handler, "Hello World");
        

        话虽如此,还有其他与代表合作的方式。您可以使用FuncAction 代表。 Func 是一个委托,它指向一个接受一个或多个参数并返回一个值的方法,也就是说,它不返回 voidAction 是一个委托,它指向一个方法,该方法反过来接受一个或多个参数但不返回任何值(返回 void)。换句话说,当您的委托指向返回 void 的方法时,您应该使用 Action

        以下是使用Action 委托的示例:

        static void Main(string[] args)
        {
            Action<string> action = new Action<string>(Display);
            action("Hello!!!");
            Console.Read(); //Prevents from closing the command line right away.
        }
        
        static void Display(string message)
        {
            Console.WriteLine(message);
        }
        

        因此,类似

        void (* funcPtr)(int) = &someFuncWithAnIntArg;
        (*funcPtr)(10); 
        

        在 C# 中等价于

        Action<int> funcPtr = new Action<int>(someFuncWithAnIntArg);
        funcPtr(10);
        

        现在是Func 代表:

        static void Main(string[] args)
        {
            Func<int, double> func = new Func<int, double>(CalculateHra);
            Console.WriteLine(func(50000));
            Console.Read();
        }
        
        static double CalculateHra(int basic)
        {
            return (double)(basic * .4);
        }
        

        Func 委托接受参数并返回值的语法类似于Func&lt;TArgument, TOutput&gt;,其中TArgument 是参数的类型,TOutput 是返回值的类型。 Func(浏览左侧树索引)和Action(也浏览左侧树索引)委托的类型还有很多。

        最后但并非最不重要的是,我们有 Predicate 委托,它通常用于搜索集合或一组数据中的项目。让我们定义一些样板代码来解释:

        class Customer
        {
            public int Id { get; set; }
            public string FirstName { get; set; }
        }
        

        那么,让我们试试吧:

        static void Main(string[] args)
        {
           List<Customer> customers = new List<Customer>();
           customers.Add(new Customer { Id = 1, FirstName = "Stack" });
           customers.Add(new Customer { Id = 2, FirstName = "Overflow" });
        
           Predicate<Customer> pred = x => x.Id == 1;
           Customer customer = customers.Find(pred);
           Console.WriteLine(customer.FirstName);
           Console.Read();
        }
        

        最后一个代码 sn-p 将打印“堆栈”。发生的事情是名为prepPredicate 委托被用作在列表customers 中搜索的搜索条件。基本上,这个委托在列表的每个元素x 上运行,当x.Id == 1 它返回true,否则返回false。谓词返回truex 元素作为Find 方法的结果返回。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-12
          • 2010-11-16
          • 2014-07-14
          • 1970-01-01
          • 2023-03-13
          • 2011-09-13
          相关资源
          最近更新 更多