简体   繁体   English

行动 <T> 相当于属性

[英]Action<T> equivalent for properties

I have a class that instantiates two classes which implement interfaces. 我有一个类实例化两个实现接口的类。 I want one class to notify another class that something is OK. 我想要一个类通知另一个类,某些东西没问题。 I could do it with an Action and then use private variables in the class but wondered if there was a direct way of doing it with properties so that when a property's value changes it updates a property on another class. 我可以用Action执行它然后在类中使用私有变量但是想知道是否有直接的方法来使用属性,这样当属性的值更改时它会更新另一个类的属性。

For example: 例如:

public class MyClass
{
  public ILogger Logger {get;set;}
  public ILogic Logic {get;set;}

  private Form MyWinform;

  public void Setup()
  {
    MyWinform = new MyWinform();
    MyWinform.StartBatch += Logger.CreateFile; //Create file when user presses start

    //How can I set a property on ILogic to be AllOk once ILogger says so??

    //I could use an Action so that once all is ok I call IDecidedAlOK in ILogger which
    //can then assign a private bool variable inside the class

    Logic.ItsOKMethodSoSetVariableToTrue = Logger.IDecidedAllOKMethod;

  }

  public void DataIn(string Value)
  {
     Logic.DataIn(Value);
  }

  public void CreateInstances()
  {
     Logger = new FileLogger();
     Logic = new MyLogic();
  }

}

public class MyLogic : ILogic
{
   public void DataIn(string Value)
  {
     //I want to check that all is ok before I do anything

     //if (!AllOK) 
     //return;

     //Do stuff
  }
}

实现INotifyPropertyChanged接口并订阅PropertyChanged事件

I feel like it might be a bit more conventional to have your ILogger interface expose something like a "FileCreated" or "Ready" event, and allow your application to handle that event in order to update the ILogic object (or do whatever else is necessary). 我觉得让ILogger接口暴露类似“FileCreated”或“Ready”事件可能会更常规,并允许您的应用程序处理该事件以更新ILogic对象(或做任何其他必要的事情) )。

EDIT: my apologies, after re-reading the question, I think I misunderstood what you were asking for. 编辑:道歉,在重新阅读问题之后,我想我误解了你的要求。

There isn't any "natural" object that does exactly what you're asking, but you could create an anonymous delegate (or lambda expression) for this purpose: 没有任何“自然”对象可以完全满足您的要求,但您可以为此创建一个匿名委托(或lambda表达式):

Action<bool> loggerResult = (value) => Logic.ItsOKMethodSoSetVariableToTrue = value;

一个属性内部由两个私有方法组成,一个是get_XXX和一个set_XXX,所以除非你想获取那些方法的MethodInfo并调用它们(它们再次是方法),否则你别无选择,只能实现方法调用方法。

Subscribing to event ( INotifyPropertyChanged or some custom one) is OK, so is the method to pass a lambda-setter, but in some cases it might be more convinient to use a shared context object (much like the shared memory concept): 订阅事件( INotifyPropertyChanged或一些自定义的)是正常的,传递lambda-setter的方法也是如此,但在某些情况下,使用共享上下文对象可能更方便(很像共享内存概念):

class ConversationContext
{
   public bool EverythingIsOK { get; set;}
}

This object is passed to all interested objects ( ILogic and ILogger ) and they operate directly on it, instead of some internal properties. 该对象被传递给所有感兴趣的对象( ILogicILogger ),它们直接在它上面运行,而不是一些内部属性。 If change notifications are required, Implement INotifyPropertyChanged on it. 如果需要更改通知,请在其上实施INotifyPropertyChanged

One positive aspect of this approach is that you won't get tangled in repeatedly firing events triggering other events and so on. 这种方法的一个积极方面是你不会纠结于反复触发事件触发其他事件等等。 A single object will hold the current state and no recurrent updates are needed. 单个对象将保持当前状态,不需要重复更新。

Again, this is just one of many options. 同样,这只是众多选择中的一种。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM