Предоставить метод .NET в качестве обратного вызова делегата
Каков синтаксис передачи .NET-метода в качестве обратного вызова делегата для объекта .NET в PowerShell.
Например:
С#:
public class Class1
{
public static void MyMethod(Action<object> obj)
{
obj("Hey!");
}
}
public class Class2
{
public static void Callback(object obj)
{
Console.Writeline(obj.ToString());
}
}
PowerShell:
[Class1]::MyMethod([Class2]::Callback)
Это не работает.
Ответы
Ответ 1
Рабочий код через чат Адама и Ойсина.
Add-Type -Language CSharpVersion3 -TypeDefinition @"
using System;
public class Class1
{
public static void MyMethod(Action<object> obj)
{
obj("Hey!");
}
}
public class Class2
{
public static void Callback(object obj)
{
Console.WriteLine(obj.ToString());
}
}
"@
$method = [Class2].GetMethod("Callback")
$delegate = [System.Delegate]::CreateDelegate([System.Action[Object]], $null, $method)
[Class1]::MyMethod($delegate)
Ответ 2
Через @oising в Twitter:
@adamdriscoll вы испорчены С# Вывод делегата компилятора. Вы нужно явно обновить это действие, старый школьный стиль.
$method = [Class2].GetMethod("Callback")
$delegate = [System.Delegate]::CreateDelegate([System.Action[Object]], $null, $method
[Class1]::MyMethod($delegate)
Ответ 3
$code = @'
using System;
public class Class1
{
public static void MyMethod(Action<object> obj)
{
obj("Hey!");
}
}
public class Class2
{
public static void Callback(object obj)
{
Console.WriteLine(obj.ToString());
}
}
'@
Add-Type -TypeDefinition $code -Language CSharpVersion3
[class1]::mymethod([system.action]::CreateDelegate('System.Action[Object]', [class2].getmethod('Callback')))
Ответ 4
Тип [Class2]::Callback
- System.Management.Automation.PSMethod
, который, по-видимому, не может быть преобразован ядром в требуемый делегат.
Я не уверен, что это лучший способ решения задачи (я не видел никакой официальной документации об этом), но приведенный ниже код работает для меня в этом примере и других подобных случаях в моей практике:
[Class1]::MyMethod({ [Class2]::Callback($args[0]) })
Ядро может преобразовать наш script блок { [Class2]::Callback($args[0]) }
в требуемый делегат.
P.S. Хотя это напрямую не связано с вопросом, но вот еще один рабочий пример этого метода: использование script блоков в качестве делегатов оценки соответствия в регулярных выражениях:
Как сортировать по имени файла так же, как Windows Explorer?
Ответ 5
Я не эксперт на С#, но после прочтения нескольких статей кажется, что вы пытаетесь использовать общие делегаты. Ваш метод обратного вызова не является общим делегатом, он даже не является делегатом.
Я думаю, что это то, что вам нужно сделать:
С#
public class Class1
{
public static void MyMethod(Action<object> obj)
{
obj("Hey!");
}
}
public class Class2
{
public Action<object> CallBack = obj => Console.WriteLine(obj.ToString());
}
Powershell:
[Class1]::MyMethod([Class2]::Callback)