【问题标题】:Linking Array Properties链接数组属性
【发布时间】:2018-12-22 14:17:38
【问题描述】:

我有一个类(Winforms 应用程序),它监视一组实际开关的状态,并将它们的打开/关闭状态存储在两个数组中。一个数组是二进制 (0,1) 格式的状态,另一个是字符串(“打开”、“关闭”)格式。 UI 使用字符串格式,内部计算使用两种格式,所以我需要两个数组。

我一直在努力寻找链接这两个数组的最佳方式,这样如果应用程序设置了任一数组的一个元素,另一个数组的相应元素会同时自动设置为正确的格式。

我考虑过使用某种绑定,但显然 Winforms 不会在属性之间进行绑定,只有 WPF。我还考虑过使用每个属性的 Set 来设置其他元素的逻辑(见下文),但我不知道如何配置 Set 以访问单个数组元素(可能是索引器,尽管我不确定如果那是正确的道路,因为我对他们一无所知)。

这是我目前的代码,当然它不起作用,因为它不知道如何将数组与逻辑语句中的 int 等同起来。

任何有关解决方案的帮助将不胜感激。谢谢。

public class SystemStatus
{
    public string[] strStatus
    {
        get
        {
            return strStatus;
        }
        set
        {
            strStatus = value;
            binStatus = value == "closed" ? 1 : 0;
        }
    }
    public int[] binStatus
    {
        get
        {
            return binStatus;
        }
        set
        {
            binStatus = value;
            strStatus = value == 1 ? "closed" : "open";
        }
} 

【问题讨论】:

  • 您的strStatus 是数组,因此value 也是数组,但在binStatus = value == "closed" ? 1 : 0; 中您将其视为字符串。
  • 是的,这就是为什么我说“当然它不起作用,因为它不知道如何将数组与逻辑语句中的 int 等同起来。”正如一位伟大的哲学家曾经说过的那样,“(重述问题)!=(提供解决方案)”。 :)
  • 老实说,我不明白你真正需要什么,但我猜你有 几个 开关,你需要同时存储 stringint价值观。我认为你需要DictionaryDataTable
  • 当T是你的“Switch”对象时,你应该使用一个数组,并且每个对象都有一个字符串属性和一个字节属性来表示状态,你也可以添加一个开关ID/mac的属性地址等...
  • 再次,我说“监控一组实际开关的状态,并将它们的打开/关闭状态存储在两个数组中”,所以是的,有多个开关。而且我不确定拥有一系列开关与此有什么关系。我只想维护两个状态数组。

标签: c# arrays winforms


【解决方案1】:

UI 使用字符串格式……所以我需要两个数组

我想说最好的解决方案是拥有一个布尔数组,并修改您的 UI 代码以将布尔值呈现为打开/关闭或其他。如果您需要帮助,请发布一些 UI 代码,但它应该很简单。例如通过使用如下扩展方法:

public string ToOpenClosed(this bool value)
{
    return value ? "open" : "closed";
}

【讨论】:

  • 再次,这要求每次我需要访问 UI 时都需要调用一个转换方法。作为属性值转换,自动执行一次似乎效率更高。这样我就可以直接访问必要的版本,布尔或字符串。
  • 有谁知道我如何在属性的 SET 方法中访问任一数组的单个元素?这样如果我想设置,例如上面例子中的binStatus[2],它也会设置strStatus[]的对应元素吗?我认为这会解决我的问题,除非有人知道链接两个数组的更好方法。
  • 所以你们不知道答案,但还是把我的问题记下来?认真的吗?
  • @ebergerly - 我没有否决你的问题。您说“执行一次似乎效率更高”-我不同意-我敢打赌,性能差异将无法衡量,但是如果不查看您的 UI 代码,就无法为您提供更多详细信息。您可以在 WinForms 中进行数据绑定并实现:docs.microsoft.com/en-us/dotnet/framework/winforms/… 并可以实现 MVC/MVP 模式。
  • @ebergerly - 数组属性的设置器替换整个数组,而不是您想要的。你可以有一个类似SetSwitch(int index, bool isOpen) 的方法,它将两个数组中的值设置在指定的索引处。或者有一组自定义Switch 对象,如@jonathana 对您的问题的评论中所建议的那样
【解决方案2】:

不太确定你的目标,但你可以试试这个:

class SystemStatus
    {
        private string[] strStatus_;
        private int[] binStatus_;

        public string[] strStatus
        {
            get
            {
                return strStatus_;
            }
            set
            {
                strStatus_ = value;
                binStatus_ = new int[strStatus_.Length];
                for (int i = 0; i < strStatus_.Length; i++)
                {
                    binStatus_[i] = strStatus_[i] == "closed" ? 1 : 0;
                }

            }
        }
        public int[] binStatus
        {
            get
            {
                return binStatus_;
            }
            set
            {
                binStatus_ = value;
                strStatus_ = new string[binStatus_.Length];
                for (int i = 0; i < binStatus_.Length; i++)
                {
                    strStatus_[i] = binStatus_[i] == 1 ? "closed" : "open";
                }
            }
        }

【讨论】:

  • 谢谢。但这不会导致无限循环/堆栈溢出吗?当您设置一个数组时,它会设置另一个数组,然后设置另一个数组,等等?
  • 没有。试试看。它作用于类 private 属性
  • 道歉。是的,你是对的,它似乎工作正常。我现在的问题是,当我设置 binStatus 元素时,它不会更新并设置相应的 strStatus 元素。我正在看 binStatus,它们用 SET 更新得很好,但是字符串数组在通过 for 循环运行时不会改变。不能访问属性中数组的单个元素吗?
【解决方案3】:

你可以这样做:

strStatus = value.Select(v => v == 1 ? "closed" : "open").ToArray();

还有:

binStatus = value.Select(v => v == "closed" ? 1 : 0).ToArray();

更完整的解决方案:

private string[] _strStatus;
private int[] _binStatus;

public string[] strStatus
{
    get
    {
        return _strStatus;
    }
    set
    {
        _strStatus = value;
        _binStatus = value.Select(v => v == "closed" ? 1 : 0).ToArray();
    }
}
public int[] binStatus
{
    get
    {
        return _binStatus;
    }
    set
    {
        _binStatus = value;
        _strStatus = value.Select(v => v == 1 ? "closed" : "open").ToArray();
    }
}

【讨论】:

  • 我可能是错的,但我认为这与其他建议的解决方案存在相同的问题,即无限循环/堆栈溢出。还是我错过了什么?
  • 我不这么认为,它只设置了与属性同名但以下划线开头的私有支持字段。
  • 谢谢,你是对的。我也尝试了这个解决方案,但与其他建议的解决方案相同,它似乎忽略了 lambda 表达式,并且不会更改任何 strStatus 元素,因为 binStatus 元素获取 SET。也许正如@Joe 提到的,setter 只替换了整个数组,所以它忽略了任何设置单个元素的尝试?
猜你喜欢
  • 2019-01-09
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-15
相关资源
最近更新 更多