扩展方法和GetBytes实现

时间:2010-06-23 00:00:59

标签: c# list extension-methods

我想在List类上使用GetBytes扩展方法...

public static class Extensions
{
    public static byte[] GetBytes<T>(this ICollection<T> col)
    {
        List<byte> bytes = new List<byte>();
        foreach (T t in col)
            bytes.AddRange(BitConverter.GetBytes(t));

        return bytes.ToArray();
    }
}

当我编译时,我收到一个编译错误,声明参数'1':无法从'T'转换为'double'。任何人都可以向我解释这个问题是什么吗?

1 个答案:

答案 0 :(得分:6)

BitConverter没有适用于任意类型的GetBytes实现。您必须传递正确类型的参数,例如double,int等。

编译器没有找到适当的重载,并且“默认”为双重过载,然后将其报告为编译器错误。


为了在一般类型上使用它,您还需要传入一个转换为字节的Func。这可行:

public static class Extensions
{
    public static byte[] GetBytes<T>(this IEnumerable<T> col, Func<T, byte[]> conversion)
    {
        return col.SelectMany(conversion).ToArray();
    }
}

然后您可以使用它:

static void Main(string[] args)
{
    double[] test = new double[3]
                        {
                            0, 12, 14.12
                        };
    List<int> ilist = new List<int>() { 3,5,1 };

    byte[] doubles = test.GetBytes(BitConverter.GetBytes);
    byte[] ints = ilist.GetBytes(BitConverter.GetBytes);


    Console.WriteLine("Double collection as bytes:");
    foreach (var d in doubles)
    {
        Console.WriteLine(d);
    }

    Console.WriteLine("Int collection as bytes:");
    foreach (var i in ints)
    {
        Console.WriteLine(i);
    }           

    Console.ReadKey();
}

不幸的是,“BitConverter.GetBytes”行(或其他一些执行此转换的函数)使API调用不那么“漂亮”,但它确实可以正常工作。可以通过添加重载来删除特定类型的T,例如:

public static class Extensions
{
    public static byte[] GetBytes(this IEnumerable<double> col)
    {
        return GetBytes<double>(col, BitConverter.GetBytes);
    }

    public static byte[] GetBytes(this IEnumerable<int> col)
    {
        return GetBytes<int>(col, BitConverter.GetBytes);
    }
    // Add others as needed

    public static byte[] GetBytes<T>(this IEnumerable<T> col, Func<T, byte[]> conversion)
    {
        return col.SelectMany(conversion).ToArray();
    }
}

编辑:由于您需要避免使用SelectMany,您可以像以前一样编写main函数。 SelectMany让这更简单:

public static class Extensions
{
    public static byte[] GetBytes<T>(this IEnumerable<T> col, Func<T, byte[]> conversion)
    {
        List<byte> bytes = new List<byte>();
        foreach (T t in col)
            bytes.AddRange(conversion(t));

        return bytes.ToArray();
    }
}