简体   繁体   中英

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

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

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM