Home > Software engineering >  Can we pass C# delegate as a method parameter? If so how to pass an argument?
Can we pass C# delegate as a method parameter? If so how to pass an argument?

Time:11-22

I have the following code snippet with me.

public class SomeClass
{
    private int[] items;
    public unsafe T DoSomething<T>(delegate*<int[], T> abc)
    {
        return abc(items);
    }
}

I want to pass HowToDoSomething(int[] values) to above the Dosomething method without using Func.

class Program
    {
        static void Main(string[] args)
        {
            int[] myItems= { 1, 2, 3, 4};
            SomeClass sc = new SomeClass(myItems);

            //How to call DoSomething here with delegate*<int[], T>
            //without using changing DoSomething signature with Func
        }

        public static int HowToDoSomething(int[] values)
        {
            return 1;
        }
    }

P.S. What does the asterisk symbol does in public unsafe T DoSomething<T>(delegate*<int[], T> abc)? Is it a type pattern?

UPDATE:

I tried below yet I am a stuck atm on figuring out how to pass the delegate to sc.DoSomething

class Program
        {
            static void Main(string[] args)
            {
                int[] myItems= { 1, 2, 3, 4};
                SomeClass sc = new SomeClass(myItems);

                HowToDoSomethingDelegate hwtdsd = new HowToDoSomethingDelegate(HowToDoSomething);
                

                //How to call DoSomething here with delegate*<int[], T>
                //without using changing DoSomething signature with Func
            }
    
            public static int HowToDoSomething(int[] values)
            {
                return 1;
            }

            public delegate int HowToDoSomethingDelegate(int[] vs)
        }

CodePudding user response:

In the method

public unsafe T DoSomething<T>(delegate*<int[], T> abc)
{
    return abc(items);
}

the expected argument abc is defined as a pointer to a delegate that expects an argument of type int[] and returns a value of type T.

The asterisk has the meaning "pointer to". Pointers can only be used in an unsafe context. That's why the method DoSomething is marked as unsafe.

In order to call the method and pass your own method as a pointer, you need to

  1. perform the call in an unsafe context using the unsafe keyword and
  2. use the ampersand symbol & to get the pointer to your method. The ampersand has the meaning "get pointer for" / "get address of".

Code:

private void button1_Click(object sender, EventArgs e)
{
    SomeClass c = new SomeClass();
    unsafe
    {
        c.DoSomething<int>(&HowToDoSomething);
    }
}

public static int HowToDoSomething(int[] values)
{
    return 1;
}

Now why you would want to use pointers and unsafe code is a question that needs answering. Using unsafe code carries lots of risks and has very few advantages.

CodePudding user response:

If you use Func:

public T DoSomething<T>(Func<int[],T> abc)
{
    return abc(items);
}

you can do this :

SomeClass sc = new SomeClass();
string s = sc.DoSomething<string>((items) =>
{
   return "Hello";
});
  • Related