2

I am trying to create a delegate on an Action<> type with a by-ref parameter as argument. But I am stuck on how to achieve this.

That's what I got so far:

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

The issue with using "t1" in the delegate is, that the signature does not match. That is kindof expected, as I am passing the struct by reference.

t2 does not work either, as it complains that I can not use a By-ref parameter as argument list type. :(

Is there a way to create the delegate with to Foo in my example? Or do I have to drop the in-modifier?

1 Answers1

3

No, you cannot create an Action<T> with a by-ref parameter, because that aspect is part of the delegate signature, which is pre-defined and outside of your control. You will have to define your own delegate type, as you have done with Foo. This delegate type could be generic, but cannot declare variance - neither covariance nor contravariance is compatible with by-ref parameters (of the variant type).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks, the hint "This delegate type could be generic" was kindof what I was missing :). Now I am almost at my goal... do you also happen to know how to get the non-ref type given you have a byref type? I.e. in my example above, how to get to "typeof(MyStruct)" if I have an instance of Type "MyStruct&"? I mean, I _could_ do things like `Type.GetType(mytype.AssemblyQualifiedName.Replace("&", ""))` but that is kindof... urks! – Immanuel Scholz Apr 17 '21 at 21:02
  • got it. `mytype.GetElementType()` – Immanuel Scholz Apr 17 '21 at 21:23