Создать конкретный делегат из совместимого обобщенного делегата?C#

Место общения программистов C#
Ответить
Anonymous
 Создать конкретный делегат из совместимого обобщенного делегата?

Сообщение Anonymous »

У меня есть метод расширения, созданный для дебатации действия делегировать функции. Предназначен для использования в обработчиках событий и еще много чего, которые испускают много событий, которые я хочу ограничить. < /P>

Код: Выделить всё

public static Action Debounce(this Action debounceDelegate, int delayMs = 500)
{
TArg? triggerArg = default;
Timer? triggerTimer = default;
return DebounceHandler;

void DebounceHandler(TArg arg)
{
triggerArg = arg;
if (triggerTimer is null)
triggerTimer = new(TriggerDelegate, null, delayMs, Timeout.Infinite);
else
triggerTimer.Change(delayMs, Timeout.Infinite);
}
void TriggerDelegate(object? _)
{
var arg = triggerArg;
var @delegate = debounceDelegate;
triggerArg = default;
triggerTimer!.Dispose();
triggerTimer = null;
@delegate.Invoke(arg);
}
}
< /code>
Это прекрасно работает для моего варианта использования, но я хотел обобщить это, чтобы работать для всех основных делегатов (по сути, все типы действий, потенциально все типы фанков). Технически кажется, что это должно быть простой, та же структура и использовать Delegate.dynamicinvoke (объект? Проблема заключается в создании обработчика, который такой же, как и исходный тип делегата, я не знаю, как его создать. < /P>
public static TDelegate Debounce(this TDelegate debounceDelegate, int delayMs = 500)
where TDelegate : Delegate
{
object?[]? triggerArgs = default;
Timer? triggerTimer = default;
return MagicConversion(DebounceHandler); // need this magic conversion function

void DebounceHandler(object?[]? args)
{
triggerArgs = args;
if (triggerTimer is null)
triggerTimer = new(TriggerDelegate, null, delayMs, Timeout.Infinite);
else
triggerTimer.Change(delayMs, Timeout.Infinite);
}
void TriggerDelegate(object? state)
{
var args = triggerArgs;
var @delegate = debounceDelegate;
triggerArgs = default;
triggerTimer!.Dispose();
triggerTimer = null;
@delegate.DynamicInvoke(args);
}
}
< /code>
private static TDelegate MagicConversion(Action @delegate)
where TDelegate : Delegate
{
// TODO: implement me
}
< /code>
I'm able to convert a function from arbitrary delegate to Delegate(object?[] args)
с использованием delegate.dynamicinvoke () . Существует ли доступный метод «обратного», который может преобразовать общего делегата обратно в конкретный делегат? Но давайте придерживаться общего случая.

Подробнее здесь: https://stackoverflow.com/questions/797 ... d-delegate
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»