繁体   English   中英

C#使用泛型函数将参数传递给具有许多重载的函数

[英]c# use a generic function to pass parameter to a function with many overloads

我正在尝试创建以下功能:

    public static byte[] ValueToBigEndian<T>(T data)
    {
        byte[] bytes;
        // We want to use big endian
        if (BitConverter.IsLittleEndian)
        {
            bytes = BitConverter.GetBytes(data).Reverse().ToArray();
            //bytes.Take(System.Runtime.InteropServices.Marshal.SizeOf(data)); // probabl don't need this
        }
        else
        {
            // Host is big endian already
            bytes = BitConverter.GetBytes(data;
            //bytes.Take(System.Runtime.InteropServices.Marshal.SizeOf(data)); // probabl don't need this
        }

        return bytes;
    }

所以在这里我使用的不是BitConverter.GetBytes(...) ,它不是通用的,但是有很多重载( ushortintboolulonglongshort等)。

我试图避免为每个函数编写匹配的重载函数,所以我的想法是使用泛型函数。 恕我直言,这将运行良好,直到有人尝试使用不在重载列表中的类型,然后编译器会抱怨。 但是编译器立即抱怨,因为类型T没有重载。

我得到的错误是

错误CS1503参数1:无法从“ T”转换为“ bool”

有没有办法实现我在这里尝试的功能?

之所以会这样,是因为无法对值类型进行模板化。 就个人而言,我认为这是C#失败,尽管开发人员对此有何表述,但始终会导致重复。

您所能做的就是为每种值类型创建重载...

更新资料

另一种更肮脏的方法是通过反思解决这一问题。 您实际上可以通过执行以下操作获取所需的方法:

    public static byte[] GetBytesTemplated<T>(T value) where T : struct
    {
        var method = typeof(BitConverter).GetMethod("GetBytes", new[]{typeof(T)});
        return (byte[])method.Invoke(null, new object[]{value});
    }

但是,通过这种方式,您需要自己检查模板的值类型。 您的最终代码将如下所示:

public static byte[] ValueToBigEndian<T>(T data) where T : struct
{
    byte[] bytes = GetBytesTemplated(data);
    // We want to use big endian
    if (BitConverter.IsLittleEndian)
    {
        Array.Reverse(bytes);
    }
    return bytes;
}

逻辑上可以做到这一点。 但是,没有任何通用类型(除Object以外)的所有值类型都可以从BitConverter.GetBytes任何重载继承而来作为参数。

相反,您可以做的一件事是改为使用通用参数,只是相信传递给该方法的值是BitConverter.GetBytes的有效参数类型之一:

public static byte[] ValueToBigEndian(dynamic data)
{
    byte[] bytes = BitConverter.GetBytes(data);

    if (BitConverter.IsLittleEndian)
        Array.Reverse(bytes);

    return bytes;
}

与使用反射相比,我更喜欢这种方法,因为它更容易理解正在发生的事情,而且我相信它也可以运行得更快(未经声明的声明)。 但是,就像反射一样,您必须自己进行类型检查,以捕获传递不兼容类型的对象的情况。 (可以通过try-catch处理,但是我不确定是否一定将其视为“最佳实践”。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM