0

Let's look at this situation:

private Func<int, int> callback;
public SomeClass(Func<int, int> callback)
{
    this.callback = callback;
}

Then later we can call that function with

callback(5);

and it would return a number.

Now, what I want is something like the following

private Func<T1, T2> callback;
public SomeClass(Func<T1, T2> callback)
{
    this.callback = callback;
}

That delegate would accept a function with a signature like

public T1 SomeFunc<T1, T2>(T2)

and could be called by

callback<int, string>("hello")

which would return an int.

Can this be done in C#?

2
  • 1
    Site note: Func<T1, T2> returns T2, so your example would take a string and return an int... Commented Apr 5, 2012 at 19:31
  • It's been a while since I've asked this question and what I didn't know at the time is that what I wanted is called a rank-2 type. This (currently) can't be typed in C#. Commented Jan 1, 2017 at 13:51

3 Answers 3

1

If you're storing the callback locally, the easiest thing would be to make the class generic:

public class SomeClass<TParam, TReturn>
{
    private Func<TParam, TReturn> _callback;

    public class SomeClass(Func<TParam, TReturn> callback)
    {
        _callback = callback;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Yeah but the thing is, I don't want to restrict myself to one type per instance. The function that will be passed in the callback will be able to output different types of data.
Then use a Func<object,object>. I don't know how useful it will be though.
I think you could make a generic method, then store the callback as a Delegate object.
1

Sure, but you'll need to make the class generic as well.

Class SomeClass<T1, T2>
{
    private Func<T1, T2> callback;
    public SomeClass(Func<T1, T2> callback)
    {
        this.callback = callback;
    }
 }

Comments

1

Using properties you will have to make the class generic like the other posters said.

It looks a little weird, but if you don't want your class to be generic then you could use generic methods to get and set the callback function, but the downside is that you will have to devise some way to keeping track of the types since you will need to pass them in to call call back. Not sure how useful this would actually be.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{

    public class CallbackTest
    {
        public CallbackTest(){}

        private object _CallBack = null;

        public Func<T1, T2> GetCallBack<T1,T2>()
        {            
                return (Func<T1, T2>)_CallBack;
        }

        public void SetCallBack<T1, T2>(Func<T1, T2> value)
        {
            _CallBack = value;
        }



    }
    class Program
    {
        static void Main(string[] args)
        {

            CallbackTest t = new CallbackTest();
            t.SetCallBack(new Func<int, int>(x => x * x));

            Console.WriteLine(t.GetCallBack<int, int>()(10));

            t.SetCallBack(new Func<string, string>(x => x.ToUpper()));

            Console.WriteLine(t.GetCallBack<string, string>()("test"));

            Console.ReadLine();


        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.