Как создать универсальный тип в делегате действия с параметром ByRef?

Я пытаюсь создать делегата для типа Action<> с параметром by-ref в качестве аргумента. Но я застрял в том, как этого добиться.

Вот что у меня получилось:

      using System;

class Program
{
    struct MyStruct { }
    static void FooFn(in MyStruct s) { }
    delegate void Foo (in MyStruct s);

    public static void Main(string[] args)
    {
        Foo f = FooFn;

        var t1 = typeof(Action<>).MakeGenericType(typeof(MyStruct));
        var t2 = typeof(Action<>).MakeGenericType(typeof(MyStruct).MakeByRefType());

        var d = Delegate.CreateDelegate(t1, null, f.Method);
    }
}

Проблема с использованием «t1» в делегате заключается в том, что подпись не совпадает. Это вроде как ожидается, поскольку я передаю структуру по ссылке.

t2 тоже не работает, так как жалуется, что я не могу использовать параметр By-ref в качестве типа списка аргументов. :(

Есть ли способ создать делегата с помощью Foo в моем примере? Или надо убрать in-модификатор?

1 ответ

Нет, вы не можете создать Action<T>с параметром by-ref, потому что этот аспект является частью сигнатуры делегата , которая заранее определена и находится вне вашего контроля. Вам нужно будет определить свой собственный тип делегата, как вы это сделали с Foo. Этот тип делегата может быть универсальным, но не может объявлять дисперсию - ни ковариация, ни контравариантность не совместимы с параметрами по ссылке (типа вариант).

Другие вопросы по тегам