Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#使用泛型函数将参数传递给具有许多重载的函数_C#_Templates_Generics - Fatal编程技术网

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

c#使用泛型函数将参数传递给具有许多重载的函数,c#,templates,generics,C#,Templates,Generics,我正在尝试创建以下函数: public static byte[] ValueToBigEndian<T>(T data) { byte[] bytes; // We want to use big endian if (BitConverter.IsLittleEndian) { bytes = BitConverter.GetBytes(data).Reverse().ToAr

我正在尝试创建以下函数:

    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;
    }
公共静态字节[]值ToBigendian(T数据)
{
字节[]字节;
//我们想用big-endian
if(位转换器.IsLittleEndian)
{
bytes=BitConverter.GetBytes(数据).Reverse().ToArray();
//bytes.Take(System.Runtime.InteropServices.Marshal.SizeOf(data));//probabl不需要这个
}
其他的
{
//主持人已经是大端人了
字节=位转换器.GetBytes(数据;
//bytes.Take(System.Runtime.InteropServices.Marshal.SizeOf(data));//probabl不需要这个
}
返回字节;
}
所以我在这里使用的是
BitConverter.GetBytes(…)
,它不是泛型的,但是它有很多重载(
ushort
int
bool
ulong
long
short
,等等)

我试图避免为每种类型编写匹配的重载函数,因此我的想法是使用泛型函数。在有人尝试使用重载列表中不包含的类型之前,这将正常运行,然后编译器会抱怨。但是编译器会立即抱怨,因为类型
T
没有重载

我得到的错误是

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


有什么方法可以实现我在这里所尝试的吗?

之所以会出现这种情况,是因为无法对值类型进行模板化。我个人认为,这是C#fail,不管开发人员怎么说,它总是会导致重复

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

更新

另一种更肮脏的方法是通过反射来解决这个问题。通过这样做,您实际上可以获得所需的方法:

    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});
    }
公共静态字节[]GetBytesTemplated(T值),其中T:struct
{
var method=typeof(BitConverter).GetMethod(“GetBytes”,new[]{typeof(T)});
return(byte[])method.Invoke(null,新对象[]{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;
}
公共静态字节[]值ToBigendian(T数据),其中T:struct
{
字节[]字节=GetBytesTemplated(数据);
//我们想用big-endian
if(位转换器.IsLittleEndian)
{
Array.Reverse(字节);
}
返回字节;
}

之所以会出现这种情况,是因为无法对值类型进行模板化。就我个人而言,我认为这是C#fail,不管开发人员怎么说,它总是会导致重复

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

更新

另一种更肮脏的方法是通过反射来解决这个问题。通过这样做,您实际上可以获得所需的方法:

    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});
    }
公共静态字节[]GetBytesTemplated(T值),其中T:struct
{
var method=typeof(BitConverter).GetMethod(“GetBytes”,new[]{typeof(T)});
return(byte[])method.Invoke(null,新对象[]{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;
}
公共静态字节[]值ToBigendian(T数据),其中T:struct
{
字节[]字节=GetBytesTemplated(数据);
//我们想用big-endian
if(位转换器.IsLittleEndian)
{
Array.Reverse(字节);
}
返回字节;
}

逻辑将说明这是可以完成的。但是,没有任何通用类型(除了
对象
)可以从该类型继承任何重载的
位转换器。GetBytes
可以接受为参数

您可以改为使用泛型参数,只需相信传递到方法中的值是
BitConverter.GetBytes
的有效参数类型之一:

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

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

    return bytes;
}

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

逻辑将声明这可以完成。但是,没有任何通用类型(除了
对象
)是所有值类型继承自
位转换器的任何重载。GetBytes
将接受为参数

您可以改为使用泛型参数,只需相信传递到方法中的值是
BitConverter.GetBytes
的有效参数类型之一:

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

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

    return bytes;
}

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

您不能这样做,编译器需要知道
t
可以是什么,以便解决对
GetBytes
的调用。因为
t
可以是任何类型(从签名中),也可以使用
对象
或任何其他类型,而
GetBytes
没有这样的重载。因此,我猜您想做的是不可能的,并且您一直在使用重载。您不能这样做,编译器需要知道
t
可以是什么,以便将对
GetBytes
的调用解析为
te> 可以是任何类型(从签名中),也可以是
对象
或任何其他类型,但是
GetBytes
没有这种重载。因此我猜你想做的是不可能的,你被卡住了