简体   繁体   English

C#将方法作为参数传递

[英]C# pass methods as parameters

I'm working with an C API in C#.我正在使用 C# 中的 C API。 In C Methods are passed as parameters and I'm trying to accomplish the same thing in C#.在 C 方法中作为参数传递,我试图在 C# 中完成同样的事情。

in C I would call the functions the following way:C 中,我会通过以下方式调用函数:

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

Note that the used methods are defined in the following way:请注意,使用的方法按以下方式定义:

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

In C# the methods are defined in the same way but I don't know how I can pass those methods.在 C# 中,方法以相同的方式定义,但我不知道如何传递这些方法。

C# equivalent of function pointers are delegates. C# 函数指针的等价物是委托。 You can use Func and Action to pass methods as parameters.您可以使用 Func 和 Action 将方法作为参数传递。 Func delegate represents method which takes N arguments and returns value, Action delegate represents void method. Func 委托表示接受 N 个参数并返回值的方法,Action 委托表示 void 方法。

Consider this考虑这个

void (* myFunction)(int parameter) 

in C# would be在 C# 中将是

Action<int> 

Please try this code:请试试这个代码:

create ll_scan_result_t and ll_status_t classes.创建 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
    }
}

Use the Func Delegate like below像下面这样使用 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);
    }
}

In C#, the equivalent to C/C++ function pointers are delegates .在 C# 中,与 C/C++函数指针等效的是委托 A delegate is a type that represents references to methods with a particular parameter list and return type.委托是一种类型,它表示对具有特定参数列表和返回类型的方法的引用。 When you instantiate a delegate, you can associate its instance with any method that has a compatible signature and return type.当您实例化委托时,您可以将其实例与具有兼容签名和返回类型的任何方法相关联。 You can call the method through the delegate instance.您可以通过委托实例调用该方法。

Here's an example.这是一个例子。 First, declare a delegate:首先,声明一个委托:

public delegate void Del(string message);

Now, Del is a delegate type which can be used to call to any method that returns void and accepts an argument of type string .现在, Del是一种委托类型,可用于调用任何返回void并接受string类型参数的方法。 Now, let's create some method matching the signature and return type of Del :现在,让我们创建一些匹配Del的签名和返回类型的方法:

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

Now, let's create an instance of Del and associate it with DelegateMethod , like this:现在,让我们创建一个Del实例并将其与DelegateMethod关联,如下所示:

Del handler = DelegateMethod;

If you want to call DelegateMethod , you can do it by:如果要调用DelegateMethod ,可以通过以下方式进行:

handler("Hello World");

Notice that since Del is a type, you can do something like this:请注意,由于Del是一种类型,因此您可以执行以下操作:

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

Which can be used as:可以用作:

SomeMethod(handler, "Hello World");

With that said, there are othes ways of working with delegates.话虽如此,还有其他与代表合作的方式。 You can use Func and Action delegates.您可以使用FuncAction委托。 Func is a delegate that points to a method that accepts one or more arguments and returns a value, that is, it doesn't return void . Func是一个委托,它指向一个方法,该方法接受一个或多个参数并返回一个值,即它不返回void Action is a delegate that points to a method which in turn accepts one or more arguments but returns no value (returns void ). Action是一个委托,它指向一个方法,该方法接受一个或多个参数但不返回任何值(返回void )。 In other words, you should use Action when your delegate points to a method that returns void .换句话说,当您的委托指向返回void的方法时,您应该使用Action

Here's an example of using an Action delegate:这是使用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);
}

Therefore, something like因此,像

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

Is equivalent in C# to在 C# 中等效于

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

And now for a Func delegate:现在对于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);
}

The syntax for a Func delegate accepting an argument and returning a value is like this Func<TArgument, TOutput> where TArgument is the type of the argument and TOutput is the type of returned value.接受参数并返回值的Func委托的语法如下Func<TArgument, TOutput> ,其中TArgument是参数的类型, TOutput是返回值的类型。 There are many more types of Func (browse the left tree index) and Action (also browse the left tree index) delegates.还有更多类型的Func (浏览左树索引)和Action (也浏览左树索引)委托。

And last, but not least, we have the Predicate delegates which is typically used to search items in a collection or a set of data.最后但并非最不重要的是,我们有Predicate委托,它通常用于搜索集合或一组数据中的项目。 Let's define some boilerplate code to explain:让我们定义一些样板代码来解释:

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

Then, let's try it in:那么,让我们试一试:

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

The last code snippet will print "Stack".最后一个代码片段将打印“堆栈”。 What happened is that the Predicate delegate named prep was used as a search criteria to search in the list customers .发生的事情是名为prepPredicate委托被用作搜索条件以在列表customers进行搜索。 Basically, this delegate was run on every element x of the list, and when x.Id == 1 it returns true , false otherwise.基本上,这个委托在列表的每个元素x上运行,当x.Id == 1它返回true ,否则返回false The x element where the predicate returned true is returned as the result of the Find method.谓词返回truex元素作为Find方法的结果返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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