【问题标题】:Referencing, accessing a dictionary for data引用、访问数据字典
【发布时间】:2015-03-11 17:20:36
【问题描述】:

我的程序正在使用 LibUSB 与 USB 设备通信,该设备具有按钮和 LED,用于向设备发送信息并从设备读取信息。通信是在字节数组中完成的,最长可达 1024 字节,但几乎只有前 8 个字节很重要。读取时,我们读取字节数组,我想显示哪个按钮被按下或哪个 LED 亮了。因此,我认为字典是使用的最佳解决方案 - 按钮或 LED 名称的字符串值和键的字节数组。或者可能是相反的;字符串是键,数组是值。

public class DeviceInput
    {
        public static byte[] PowerArray = { 1, 0, 0, 16, 0, 0, 0, 0 };
        public string Name { get; set; }
        public byte[] InputArray { get; set; }
        public byte[] LEDArray { get; set; }


        public DeviceInput(string name, byte[] input, byte[] led)
        {
            Name = name;
            InputArray = input;
            LEDArray = led;
        }

        public static Dictionary<byte[], string> InputDictionary()
        {
            var dict = new Dictionary<byte[], string>();
            dict.Add(PowerArray, "Power Button");

            return dict;
        }

    }

在我的主程序中:

public Dictionary<byte[], string> inputDict = DeviceInput.InputDictionary();

在我的读取方法中,我将读入的字节数组并将前 8 个字节存储到本地数组中,我使用.ContainsKey() 来查看字典是否包含键(字节数组),然后会显示给用户的值(字符串)。

byte[] data = 
{ 
    readBuffer[0], readBuffer[1], readBuffer[2], readBuffer[3],
    readBuffer[4], readBuffer[5], readBuffer[6], readBuffer[7]
};

if (inputDict.ContainsKey(data))
{
    Console.WriteLine("You pressed: " + inputDict[data]);
}

设备中的 readBuffer 工作正常,数组填充完美,与我创建的字节数组 (PowerArray) 完全相同,所以我不确定 ContainsKey 是如何工作的。即使我将字典切换到&lt;string, byte[]&gt; 并尝试使用ContainsValue 而不是ContainsKey,但没有成功。

字典是获取这些数据的最佳方式吗?我应该以不同的方式加载数据吗?我是否错误地访问它?感谢您的指导。

【问题讨论】:

  • 数组使用默认引用相等,因此即使它们包含相等的值,它们也不会评估为相等。试试array1.Equals(array2);。当你创建字典时,你可以传入一个IEqualityComparer&lt;TKey&gt;,告诉它如何比较键来处理这个问题。

标签: c# dictionary data-structures key-value libusb


【解决方案1】:

这将解决您的问题(类似于@juharr 的建议)

class PowerArrayEqualityComparer : IEqualityComparer<byte[]>
{
    public bool Equals(byte[] x, byte[] y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(byte[] obj)
    {
        return obj.Aggregate(0, (current, b) => current ^ b);
    }
}

你会以这样的形式使用你的字典:

        Dictionary<byte[], string> myDict = 
            new Dictionary<byte[], string>(new PowerArrayEqualityComparer());

或者像这样初始化它:

        var d = new Dictionary<byte[], string>(new PowerArrayEqualityComparer())
        {
            {new byte[] {0, 1, 2, 3}, "Button1"},
            {new byte[] {1, 1, 2, 3}, "Button2"}
        };

唯一不同的是在字典的构造函数中包含 PowerArrayEqualityComparer 类 - 就像这个 new PowerArrayEqualityComparer(),确保在初始化字典时它就在那里。

只有这样,您才能将byte[] 用作您的字典的TKey

所以,从那时起,下面的代码就可以正常工作了:

        var b = new byte[] {1, 1, 2, 3};
        Debug.WriteLine(d.ContainsKey(b));  

它会输出True

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 2022-06-10
    • 2022-01-07
    • 2018-09-21
    • 2017-10-25
    • 2022-01-16
    • 2019-08-20
    • 2015-04-29
    • 2015-10-24
    相关资源
    最近更新 更多