[英]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.您可以使用
Func
和Action
委托。 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
.发生的事情是名为
prep
的Predicate
委托被用作搜索条件以在列表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.谓词返回
true
的x
元素作为Find
方法的结果返回。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.