为了账号安全,请及时绑定邮箱和手机立即绑定

另一个类中的动作委托引用?

另一个类中的动作委托引用?

C#
潇潇雨雨 2022-10-23 13:45:21
我正在寻找一种方法来允许另一个类通过调用该类的方法向我的 Action 委托添加方法,而不是在第一个类上调用 Action。这就是我需要的:class Program{    static void Main(string[] args)    {        Action Execute = delegate { };        ProgramTest prog = new ProgramTest(ref Execute);        prog.AddMethod();        Execute();    }}class ProgramTest{    public Action execute;    public ProgramTest(ref Action action)    {        execute = action;    }    public void AddMethod()    {        execute += Print;    }    public void Print()    {        Console.WriteLine("test");        Console.ReadLine();    }}但是,当我调用 Execute() 时,什么也没有发生。我怎样才能让它工作?
查看完整描述

4 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

另一种选择是将(不可变的)委托放在可变容器中。


public class ActionContainer

{

    public Action Action { get; set; } = () => { };

}


class Program

{

    static void Main(string[] args)

    {

        ActionContainer execute = new ActionContainer();


        ProgramTest prog = new ProgramTest(execute);


        prog.AddMethod();


        execute.Action();

    }

}


class ProgramTest

{

    public ActionContainer execute;


    public ProgramTest(ActionContainer action)

    {

        execute = action;

    }


    public void AddMethod()

    {

        execute.Action += Print;

    }


    public void Print()

    {

        Console.WriteLine("test");

        Console.ReadLine();

    }

}


查看完整回答
反对 回复 2022-10-23
?
精慕HU

TA贡献1845条经验 获得超8个赞

你想要的是这样的:


class Program

{

    static void Main(string[] args)

    {

        Action Execute = delegate { };


        ProgramTest prog = new ProgramTest(h => Execute += h);


        prog.AddMethod();


        Execute();

    }

}


class ProgramTest

{

    public Action<Action> execute;


    public ProgramTest(Action<Action> action)

    {

        execute = action;

    }


    public void AddMethod()

    {

        execute(Print);

    }


    public void Print()

    {

        Console.WriteLine("test");

        Console.ReadLine();

    }

}

打印test到控制台。


这是这个模式的一个稍微好一点的版本:


class Program

{

    static void Main(string[] args)

    {

        Action Execute = delegate { };


        ProgramTest prog = new ProgramTest(h => Execute += h, h => Execute -= h);


        var subscription = prog.AddMethod();


        Execute();


        subscription.Dispose();

    }

}


class ProgramTest

{

    public Action<Action> _attach;

    public Action<Action> _detach;


    public ProgramTest(Action<Action> attach, Action<Action> detach)

    {

        _attach = attach;

        _detach = detach;

    }


    public IDisposable AddMethod()

    {

        _attach(Print);

        return Disposable.Create(() => _detach(Print));

    }


    public void Print()

    {

        Console.WriteLine("test");

        Console.ReadLine();

    }

}


public sealed class Disposable : IDisposable

{

    public static IDisposable Create(Action action)

        => new Disposable(action);


    private readonly Action _action;

    private int _disposed;


    private Disposable(Action action)

    {

        _action = action;

    }


    public void Dispose()

    {

        if (Interlocked.Exchange(ref _disposed, 1) == 0)

        {

            _action();

        }

    }

}

我什至会更进一步并定义一个MetaAction- 您可以随意传递它并向其添加方法。


class Program

{

    static void Main(string[] args)

    {

        Action Execute = delegate { };


        MetaAction meta = MetaAction.Create(h => Execute += h, h => Execute -= h);


        var prog = new ProgramTest(meta);


        var subscription = prog.AddMethod();


        Execute();


        subscription.Dispose();

    }

}


public class MetaAction

{

    public static MetaAction Create(Action<Action> attach, Action<Action> detach)

        => new MetaAction(attach, detach);


    public Action<Action> _attach;

    public Action<Action> _detach;


    private MetaAction(Action<Action> attach, Action<Action> detach)

    {

        _attach = attach;

        _detach = detach;

    }


    public IDisposable Subscribe(Action action)

    {

        _attach(action);

        return Disposable.Create(() => _detach(action));

    }

}


public class ProgramTest

{

    public MetaAction _meta;


    public ProgramTest(MetaAction meta)

    {

        _meta = meta;

    }


    public IDisposable AddMethod()

    {

        return _meta.Subscribe(Print);

    }


    public void Print()

    {

        Console.WriteLine("test");

        Console.ReadLine();

    }

}


public sealed class Disposable : IDisposable

{

    public static IDisposable Create(Action action)

        => new Disposable(action);


    private readonly Action _action;

    private int _disposed;


    private Disposable(Action action)

    {

        _action = action;

    }


    public void Dispose()

    {

        if (Interlocked.Exchange(ref _disposed, 1) == 0)

        {

            _action();

        }

    }

}


查看完整回答
反对 回复 2022-10-23
?
慕标5832272

TA贡献1966条经验 获得超4个赞

您可以通过调用 prog.Execute 而不是 Execute 来使其工作,就像下面的代码一样。


class Program

{

    static void Main(string[] args)

    {

        Action Execute = delegate { };

        ProgramTest prog = new ProgramTest(ref Execute);

        prog.AddMethod();

        prog.execute();

    }

}

或者您需要将 Print 方法分配给 main 方法执行委托,如下所示


class Program

{

    static void Main(string[] args)

    {

        Action Execute = delegate { };            

        ProgramTest prog = new ProgramTest(ref Execute);


        Execute += prog.Print;


        prog.AddMethod();


        Execute();


    }

}


查看完整回答
反对 回复 2022-10-23
?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

您Program可能会公开一个事件,您的其他类可能会向该事件注册另一个处理程序:


class Program

{

    public static event Action MyEvent;

    static void Main(string[] args)

    {

        ProgramTest prog = new ProgramTest();


        prog.AddMethod();


        // raise the event and invoke the registered handlers

        MyEvent?.Invoke();

    }

}


class ProgramTest

{

    private Action handler;


    public ProgramTest()

    {

        handler = Print;

    }


    public void AddMethod()

    {

        Program.MyEvent += handler;  // regsiter the execute-delegate to the event

        // or directly: Program.MyEvent += Print;

    }


    public void Print()

    {

        Console.WriteLine("test");

        Console.ReadLine();

    }

}


查看完整回答
反对 回复 2022-10-23
  • 4 回答
  • 0 关注
  • 66 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信