调用基于字符串的方法

时间:2014-10-08 09:38:57

标签: c# dictionary

我需要将字节数组转换为不同的数据类型,例如uint16uint32。以下类包含一个字典,其中将操作填充为Dictionary实例中的值。操作为BitConverter.ToUInt16BitConverter.ToUInt32

class DataTypes
{
    private Dictionary<string, Action> _dict;

    public DataTypes()
    {
        // create new dictionary
        _dict = new Dictionary<string, Action>();

        // fill dictionary with key-value pairs
        _dict.Add("uint16", BitConverter.ToUInt16);
        _dict.Add("uint32", BitConverter.ToUInt32);
        _dict.Add("sint16", BitConverter.ToInt16);
        _dict.Add("sint32", BitConverter.ToInt32);
    }

    // converts byte-array to specified type
    public object getValue(string type, byte[] data, int pos) // e.g. type = "uint16"
    {
        if (_dict.ContainsKey(type))
            return _dict[type](data, pos);
        return null;
    }
}

上面的代码没有运行,因为编译器需要一个带有'void ToUInt32()'Signature(带括号)的方法。

有谁知道我怎么能做到这一点。

2 个答案:

答案 0 :(得分:3)

您可以使用以下内容重写它:

    private Dictionary<string, Func<byte[], int, object>> _dict;

    public void DataTypes()
    {
        // create new dictionary
        _dict = new Dictionary<string, Func<byte[], int, object>>
        {
            // fill dictionary with key-value pairs
            {"uint16", (data, pos) => BitConverter.ToUInt16(data, pos)},
            {"uint32", (data, pos) => BitConverter.ToUInt32(data, pos)},
            {"sint16", (data, pos) => BitConverter.ToInt16(data, pos)},
            {"sint32", (data, pos) => BitConverter.ToInt32(data, pos)}
        };
    }

    // converts byte-array to specified type
    public object getValue(string type, byte[] data, int pos) // e.g. type = "uint16"
    {
        if (_dict.ContainsKey(type))
            return _dict[type](data, pos);
        return null;
    }

答案 1 :(得分:2)

Agumenting Ivan Zub's answer:每次实例化类时都不需要重新创建字典,可以将字典放在静态字段中。

public class DataTypes
{
    private static readonly IReadOnlyDictionary<string, Func<IEnumerable<byte>, int, object>> Converters;

    static DataTypes()
    {
        Converters =
            new ReadOnlyDictionary<string, Func<IEnumerable<byte>, int, object>>(
                new Dictionary<string, Func<IEnumerable<byte>, int, object>>
                {
                    { "System.UInt16", (value, startIndex) => BitConverter.ToUInt16(value.ToArray(), startIndex) },
                    { "System.UInt32", (value, startIndex) => BitConverter.ToUInt32(value.ToArray(), startIndex) },
                    { "System.Int16", (value, startIndex) => BitConverter.ToInt16(value.ToArray(), startIndex) },
                    { "System.Int32", (value, startIndex) => BitConverter.ToInt32(value.ToArray(), startIndex) }
                });
    }

    public object GetValue(string type, byte[] value, int startIndex)
    {
        if (!Converters.ContainsKey(type))
        {
            throw new ArgumentOutOfRangeException("type");
        }

        return Converters[type](value, startIndex);
    }
}

如果班级没有其他方法(或者他们不依赖于内部状态),你可以使班级和GetValue都是静态的。