0

I was wondering if, in C#, one could pass an instance method as a delegate without an instance. For reference, this is possible in Java by doing example(InstanceClass::InstanceMethod). The compiler then turns this into the equivalent of a Func<InstanceClass, ReturnType> which calls InstanceMethod() on the provided InstanceClass like so: item=>item.InstanceMethod(). Is this possible in C# and if it is, how would one do it?

Edit: To clarify, I am asking how I can pass the method in C# without using a lambda expression. The Lambda expression given is an example of what the compiler would turn the call into. Just passing the method instead of using a Lambda expression would be useful if the method had many arguments

Edit 2: Here is an example to illustrate my question. Java:

class Instance{
    public void InstanceMethod(){System.out.println("Hello World");}
    public static void Example(){
        ArrayList<Instance> list = new ArrayList<>(5);
        list.add(new Instance());
        list.forEach(Instance::InstanceMethod)
    }
}

Output: Hello World

C#:

public class Instance{
    public void InstanceMethod(){Console.WriteLine("Hello World");}
    public static void ForEach<T>(this IEnumerable<T> input, Action<T> action){
        foreach(T item in input){
            action(item);
        }
    }
    public static void Example(){
        List<Instance> list = new ArrayList<>(5);
        list.Add(new Instance());
        list.ForEach(Instance.InstanceMethod);//error need instance to call method
    }
BrainStorm.exe
  • 1,565
  • 3
  • 23
  • 40
  • Given that you've just shown how to do it in C#, what's your question? – Servy Apr 24 '19 at 16:00
  • @Servy That is how it is done in Java – BrainStorm.exe Apr 24 '19 at 16:03
  • Your question provides a snippet of both java and C# code that does this, the former in the second sentence, the latter in the second to last sentence. – Servy Apr 24 '19 at 16:03
  • @Servy I have added a clarification. I want to be able to do it without using a Lambda expression. – BrainStorm.exe Apr 24 '19 at 16:08
  • 1
    I think the parameter should either be a delegate, which matches that method. Or do you need to specifically only allow methods from a particular class? – Andrew Apr 24 '19 at 16:08
  • I think you can look at Action or Function concept in C# – duc mai Apr 24 '19 at 16:26
  • Do you really need a list of `Instance`s? What if you just store a list of methods and then simply call them? – Andrew Apr 24 '19 at 16:37
  • Your comment is that you don't want to use lambda because the method may have arguments, but how would you pass those arguments using only the method as the parameter to ForEach? – Nikki9696 Apr 24 '19 at 16:39
  • @Nikki9696 For `DoSomething(Func method)` you do `DoSomething(Instance.BoolMethod)`. The `ForEach` is just an example. – BrainStorm.exe Apr 24 '19 at 16:49
  • @Nikki9696 It appears I misunderstood your comment. The idea is that the compiler handles the details and assumes the first type in the delegate is the item to call the method on and everything else is for method parameters. – BrainStorm.exe Apr 24 '19 at 16:54
  • I can think of a variety of ways to accomplish this, but nothing that is a direct translation like the Java example. Lambdas, reflection, method groups, Func etc. Even making your own extension method that could be used like your example, but you'd have to write it. It's not out of the box, as far as I know. If you'd like any examples, let us know, but I think your question was more about out of the box options? – Nikki9696 Apr 24 '19 at 19:06

1 Answers1

1

Even in Java you are still dealing with an instance, but Java's syntactic sugar hides that.

There is no equivalent for your case. You have to do

public static void Example()
{
    var list = new List<Instance>(5);
    list.Add(new Instance());
    list.ForEach(x => x.InstanceMethod());
}

or addstatic toInstanceMethod (since that method has no state):

public static void InstanceMethod()
{
    Console.WriteLine("Hello World");
}

public static void Example()
{
    var list = new List<Instance>(5);
    list.Add(new Instance());
    list.ForEach(x => InstanceMethod());
}

If your InstanceMethod accepted an Instance as a parameter and Example wasn't static, there is some C# syntactic sugar called a method group that would work:

public void InstanceMethod(Instance x)
{
    Console.WriteLine("Hello World");
}

public void Example()
{
    var list = new List<Instance>(5);
    list.Add(new Instance());
    list.ForEach(InstanceMethod);
}

Of all of the above, the first one is idiomatic C# and the one I would pick. It's probably the most readable and expected for C# programmers to read.

Kit
  • 20,354
  • 4
  • 60
  • 103