Reputation: 236
While I was looking at some c# code I found a new class declaration which had passed a method as a constructor’s parameter.This is my first time I have seen something like this and it has no meaning for me .Although the whole application works fine I am still interested to know what is the main idea behind the scene.
var c = new List<TheClass>
{
new TheClass(TheMethod);
}
private void TheMethod()
{
//do somthing
}
Upvotes: 2
Views: 18421
Reputation: 109567
There are many reasons that you might want to pass a method into the constructor of a class.
One of the most important is for so-called Dependency Injection, where want to inject a dependency into a class.
Suppose that a class needs to create an object. Normally, that class would do something like var item = new MyConcreteClass();
.
However, that creates a strong dependency between the class creating the object and MyConcreteClass
. This can make it harder to unit test or change implementations.
To circumvent this problem, you can do this:
MyConcreteClass
an interface (say IMyInterface
) which contains all the things you need to use from inside the class being written.Func
method which creates and returns a concrete class as IMyInterface
.Func
to create the object rather than creating it directly using new
.The Func
is therefore acting as a factory.
Code might look like this:
using System;
namespace Spacelabs.WcfDuplexDemo.Client
{
static class Program
{
static void Main()
{
var myClass = new MyClass(() => new MyConcreteClass());
myClass.DoSomething();
}
}
public interface IMyInterface
{
string MyMethod(int param);
}
public sealed class MyConcreteClass : IMyInterface
{
public string MyMethod(int param)
{
return param.ToString();
}
}
public sealed class MyClass
{
private readonly Func<IMyInterface> createMyInterface;
public MyClass(Func<IMyInterface> createMyInterface)
{
this.createMyInterface = createMyInterface;
}
public void DoSomething()
{
// Instead of var item = new MyConcreteClass(), we do the following:
var item = createMyInterface();
Console.WriteLine(item.MyMethod(12345));
}
}
Upvotes: 1
Reputation:
Are you unclear of why a method is being passed as an argument or specificly as an argument in a constructor?
CodeCaster already spoke short about Action delegates and if you're interested in storing methods in delegates like Action, I suggest you read up on Delegates here
I'd like to provide a short example of a class that contains an Action delegate: RelayCommand -> I've illustrated the use of this delegate with the MVVM pattern below:
class ViewModelDefault : INotifyPropertyChanged
{
public string TextProperty { get; set;}
public ICommand ButtonProperty
{
get {
RelayCommand relayCommand = new RelayCommand(ExecuteCommand);
return relayCommand;
}
}
private void ExecuteCommand()
{
HandlerClass handler = new HandlerClass();
handler.SaveTextInTextfile(TextboxProperty);
}
...
}
In the MVVM
pattern, your main focus is to seperate data, logic and view, which is why using Delegate
is perfect in this scenario.
You'd normally want to bind a property such as a string
from the ViewModel
to a View
UI Element such as a TextBox
.
Making use of delegates, allows you to bind a method (which would otherwise not be bindable to a UI element) through an Action property.
In the example above, the method ExecuteCommand is stored in an action field inside the RelayCommand object. This is bindable to a UI element, and will execute the method once it's requested.
Upvotes: 0
Reputation: 13495
The main idea is to defer execution of the method and control when it gets executed.
One use case for this is passing a method that creates and object so that the class controls when the object is created and it can control how many times it is created.
Upvotes: 0
Reputation: 151594
I guess the TheClass
constructor accepts an Action
delegate:
public class TheClass
{
private readonly Action _action;
public TheClass(Action action)
{
_action = action;
}
}
This way TheClass
can execute the provided action at a later time, and more than once.
For example:
public void DoAction()
{
_action();
}
You could also do:
var theClass = new TheClass(() => TheMethod());
Upvotes: 11