我正在寻找一种方法,该方法允许另一个类通过从该类中调用一个方法来向我的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()时,什么也没发生。
我如何使其工作?
答案 0 :(得分:1)
另一种选择是将(不可变的)委托放入可变容器中。
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();
}
}
答案 1 :(得分:0)
您想要的是什么
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();
}
}
}
答案 2 :(得分:0)
您可以通过调用prog.Execute而不是Execute来使其工作,就像下面的代码一样。
class Program
{
static void Main(string[] args)
{
Action Execute = delegate { };
ProgramTest prog = new ProgramTest(ref Execute);
prog.AddMethod();
prog.execute();
}
}
或 您需要将Print方法分配给主要方法执行委托,如下所示
class Program
{
static void Main(string[] args)
{
Action Execute = delegate { };
ProgramTest prog = new ProgramTest(ref Execute);
Execute += prog.Print;
prog.AddMethod();
Execute();
}
}
答案 3 :(得分:-1)
您的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();
}
}