扩展方法和 GetBytes 实现

发布于 2024-09-06 08:03:38 字数 432 浏览 5 评论 0原文

我想在 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();
    }
}

编译时,我收到一条编译器错误,指出 Argument '1':无法从 'T' 转换为 'double'。谁能向我解释一下问题是什么?

I'd like to use a GetBytes extension method on the List class...

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();
    }
}

When I compile, I am receiving a compiler error stating that Argument '1': cannot convert from 'T' to 'double'. Can anyone explain to me what the issue is?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最冷一天 2024-09-13 08:03:38

BitConverter 没有有效的 GetBytes 实现在任意类型上。您必须传递正确类型的参数,例如 double、int 等。

编译器找不到合适的重载,并且“默认”为 double 重载,然后将其报告为编译器错误。


为了在通用类型上使用它,您还需要传入一个转换为字节的 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();
    }
}

BitConverter doesn't have a GetBytes implementation that works on arbitrary types. You must pass an argument of the correct type, such as double, int, etc.

The compiler is not finding an appropriate overload, and "defaulting" to the double overload, then reporting it as a compiler error.


In order to use this on a general type, you'll need to also pass in a Func that converts to bytes. This would work:

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

You could then use this like:

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();
}

Unfortunately, the "BitConverter.GetBytes" line (or some other function to do this conversion) makes the API call a little less "pretty", but it does work correctly. This could be removed for specific types of T by adding overloads, such as:

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();
    }
}

Edit: Since you need to avoid SelectMany, you can just write the main function the same way you did previously. SelectMany just makes this simpler:

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文