将方法作为构造函数的参数传递

时间:2015-10-14 11:58:29

标签: c# constructor

当我查看一些c#代码时,我发现了一个新的类声明,它已经将一个方法作为构造函数的参数传递。这是我第一次看到类似这样的东西,对我来说没什么意义。虽然整个应用程序工作正常我仍然有兴趣知道幕后的主要想法是什么。

var c = new List<TheClass>
{
    new TheClass(TheMethod);
}

private void TheMethod()
{
    //do somthing
}

5 个答案:

答案 0 :(得分:8)

我猜TheClass构造函数接受Action delegate

public class TheClass
{
    private readonly Action _action;
    public TheClass(Action action)
    {
        _action = action;
    }
}

这种方式TheClass可以在以后执行提供的操作,并且不止一次。

例如:

public void DoAction()
{
    _action();
}

你也可以这样做:

var theClass = new TheClass(() => TheMethod());

答案 1 :(得分:1)

您可能希望将方法传递到类的构造函数中有很多原因。

最重要的一个是所谓的Dependency Injection,其中想要将依赖注入类中。

假设一个类需要创建一个对象。通常情况下,该类会执行var item = new MyConcreteClass();

之类的操作

但是,这会在创建对象的类和MyConcreteClass之间产生强烈的依赖关系。这可能会使单元测试或更改实现变得更加困难。

要解决此问题,您可以执行此操作:

  1. MyConcreteClass提取一个接口(比如IMyInterface),其中包含您正在编写的类中需要使用的所有内容。
  2. Func方法传递给类构造函数,该方法创建并返回具体类IMyInterface
  3. 在正在编写的课程中,调用Func来创建对象,而不是使用new直接创建对象。
  4. Func因此充当工厂。

    代码可能如下所示:

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

答案 2 :(得分:0)

主要思想是在执行时推迟执行方法和控制。

一个用例就是传递一个创建和对象的方法,以便类控制何时创建对象,并控制它创建的次数。

答案 3 :(得分:0)

答案 4 :(得分:0)

您是否不清楚为什么方法作为参数传递或特别是作为构造函数中的参数传递?

CodeCaster已经简短地介绍了Action代理,如果您对在Action等代理中存储方法感兴趣,我建议您阅读代理here

我想提供一个包含Action委托的类的简短示例:RelayCommand - &gt;我已经用下面的MVVM模式说明了这个委托的用法:

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

    ...
}

MVVM模式中,您主要关注的是分离数据,逻辑和视图,这就是为什么在这种情况下使用Delegate是完美的。

您通常希望将string中的ViewModel等属性绑定到View之类的TextBox UI元素。

利用委托,允许您通过Action属性绑定一个方法(否则不能绑定到UI元素)。

在上面的示例中,方法ExecuteCommand存储在RelayCommand对象内的操作字段中。这可绑定到UI元素,并在请求后执行该方法。