【问题标题】:Determine which index of an array property is being set using c#确定使用 c# 设置数组属性的哪个索引
【发布时间】:2023-03-06 09:37:01
【问题描述】:

我正在创建一个可以读取电气设备标签的 OPC 客户端。这是通过在 OPC 组中设置项目来完成的。我想要一个 bool[] 数组的属性来将项目设置为活动或非活动。我需要知道该属性 bool[] 的哪个索引用于设置该属性,以便我可以使用它来激活该项目。我可以只使用一种方法,但更喜欢属性。 _theGroup 是持有项目的 OPC 组。

private bool[] _ItemActive;    
public bool[] itemActive {
    get { return _ItemActive; }
    set {
        if (_theGroup != null) {
            int itemIndex = ?? // I don't know how to find property index access by user
            int itemHandle = itemHandles[itemIndex]; //uses index to discover handle
            _theGroup.SetActiveState(itemHandle, value, out err); // use handle to set item active
        }
        _ItemActive = value;
    }
}

用户会做这样的事情。

opcClient.itemActive[3] = false;

我需要能够发现 3 并将其插入到我的 bool[] 数组的 setter 中显示的 itemIndex 中

【问题讨论】:

    标签: c# arrays properties indexing


    【解决方案1】:

    您可以使用覆盖的索引器运算符创建自定义集合,您可以在其中执行自定义逻辑。但是创建一个setter方法SetItemActivation(int,bool)似乎是一个更干净的解决方案。

    【讨论】:

    • 我需要能够在类实例化之前和之后设置活动状态。第一个 _theGroup 将为空,因此它只会设置属性。然后当 _theGroup 启动时,它使用此属性来确定它们是否应该启动。然后在 _theGroup 运行并且不为空之后,我必须使用该组的 SetActiveState 方法激活它。所以我试图让一个属性来做这两件事。但我同意 setter 方法会更干净......
    【解决方案2】:

    我找到了一个解决方案:创建一个新类,其实例跟踪其条目的更改;每当更改索引值时,都会触发一个事件,告知哪个条目已更改以及更改为什么值。这是这样一个类(当然下面的代码可以使用泛型来替换布尔值以更通用):

    // This class tracks changes to its entries
    public class BoolArray_Tracked{
      // Set up the data for which changes at specific indices must be tracked
      private bool[] _trackedBools;
      public bool this[int itemIndex]{
        get { return _trackedBools[itemIndex]; }
        set {
          // check if something really changed
          // not sure if you want this
          if(_trackedBools[itemIndex] != value){
          _trackedBools[itemIndex] = value;
          OnIndexChanged(itemIndex, value);// Raise an event for changing the data
          }
        }
      }
    
      // Constructor
      public BoolArray_Tracked(bool[] _trackedBools){
        this._trackedBools = _trackedBools;
      }
    
      // Set up the event raiser
      public delegate void IndexEventHandler(object sender, IndexEventArgs a);
      public event IndexEventHandler RaiseIndexEvent;
    
      // Raise an event for changing the data
      private void OnIndexChanged(int indexNumber, bool boolValue){
        if (RaiseIndexEvent != null)
          RaiseIndexEvent(this, new IndexEventArgs(indexNumber, boolValue));
      }
    }
    
    // This is class enables events with integer and boolean fields
    public class IndexEventArgs : EventArgs{
      public int Index{get; private set;}
      public bool Value{get; private set;}
    
      public IndexEventArgs(int _index, bool _value){
        Index = _index;
        Value = _value;
      }
    }
    

    接下来实现 OPC 类:

    class OPC_client{
      // Tracked bool array
      public BoolArray_Tracked ItemActive{get; set;}
    
      // Constructor
      public OPC_client(bool[] boolItemActive){
        ItemActive = new BoolArray_Tracked(boolItemActive);
        ItemActive.RaiseIndexEvent += Handle_ItemActive_IndexChange;
      }
    
      // State what should happen when an item changes
      private void Handle_ItemActive_IndexChange(object sender, IndexEventArgs e){
        //if (_theGroup != null) {//Your code in the question
          int itemIndex = e.Index; 
          //int itemHandle = itemHandles[itemIndex]; //Your code
          //_theGroup.SetActiveState(itemHandle, value, out err); // Yours
        //} //Your code
    
        Console.WriteLine("The array `ItemActive' was changed"
          + " at entry " + itemIndex.ToString() 
          + " to value " + e.Value.ToString());
      }
    }
    

    最后实现一个简单的程序来测试这个

    static void Main(string[] args){
      OPC_client opcTest = new OPC_client(new bool[]{true, false});
      Console.WriteLine("Testing if message appears if value stays the same");
      opcTest.ItemActive[0] = true;
    
      Console.WriteLine();
      Console.WriteLine("Testing if message appears if value changes");
      opcTest.ItemActive[0] = false;
      Console.ReadLine();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      • 2019-04-18
      相关资源
      最近更新 更多