Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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语言中将'Int32'转换为'T','T[]`转换为'Int32[]`#_C#_.net_Arrays_Generics_Casting - Fatal编程技术网

C# 在C语言中将'Int32'转换为'T','T[]`转换为'Int32[]`#

C# 在C语言中将'Int32'转换为'T','T[]`转换为'Int32[]`#,c#,.net,arrays,generics,casting,C#,.net,Arrays,Generics,Casting,我试图编写一个简单的函数,该函数将使用RandomNumberGenerator类根据泛型参数返回Int16、Int32或Int64数组 然而,无论我如何构造代码,我似乎无法通过从T[]到short/int/long[]的非法转换,也无法通过从IntXX到T的转换。请参见下面代码中的两条注释 看来我缺少了一个基本的结构,可以绕过这个问题。有什么想法吗 public static void GenerateRandom<T> (T [] data, bool nonZeroOnly =

我试图编写一个简单的函数,该函数将使用RandomNumberGenerator类根据泛型参数返回
Int16
Int32
Int64
数组

然而,无论我如何构造代码,我似乎无法通过从
T[]
short/int/long[]
的非法转换,也无法通过从
IntXX
T
的转换。请参见下面代码中的两条注释

看来我缺少了一个基本的结构,可以绕过这个问题。有什么想法吗

public static void GenerateRandom<T> (T [] data, bool nonZeroOnly = false)
    where T: struct, System.IComparable, System.IFormattable, System.IConvertible
{
    int size = 0;
    byte [] bytes = null;

    if ((typeof(T) != typeof(byte)) && (typeof(T) != typeof(short)) && (typeof(T) != typeof(int)) && (typeof(T) != typeof(long)))
    {
        throw (new System.ArgumentException("This method only accepts types [Byte], [Int16], [Int32], or [Int64].", "<T>"));
    }

    if (typeof(T) == typeof(byte))
    {
        using (System.Security.Cryptography.RandomNumberGenerator generator = System.Security.Cryptography.RandomNumberGenerator.Create())
        {
            // Invalid cast (implicit or explicit) from T [] to byte [].
            if (nonZeroOnly) { generator.GetNonZeroBytes(data); }
            else { generator.GetBytes(data); }
        }
    }
    else
    {
        size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));    
        bytes = new byte [data.Length * size];

        using (System.Security.Cryptography.RandomNumberGenerator generator = System.Security.Cryptography.RandomNumberGenerator.Create())
        {
            if (nonZeroOnly) { generator.GetNonZeroBytes((byte []) System.Convert.ChangeType(data, typeof(byte []))); }
        else { generator.GetBytes((byte []) System.Convert.ChangeType(data, typeof(byte []))); }
        }

        using (System.IO.MemoryStream stream = new System.IO.MemoryStream(bytes))
        {
            using (System.IO.BinaryReader reader = new System.IO.BinaryReader(stream))
            {
                // Invalid cast (implicit or explicit) from short/int/long to T.
                if (typeof(T) == typeof(short)) { for (int i=0; i<bytes.Length; i+=size) { data[i] = reader.ReadInt16(); } }
                else if (typeof(T) == typeof(int)) { for (int i=0; i<bytes.Length; i+=size) { data[i] = reader.ReadInt32(); } }
                else if (typeof(T) == typeof(long)) { for (int i=0; i<bytes.Length; i+=size) { data[i] = reader.ReadInt64(); } }
            }
        }
    }
}
publicstaticvoidgenerateradom(T[]数据,bool nonzeronly=false)
其中T:struct,System.i可比较,System.IFormattable,System.i可转换
{
int size=0;
字节[]字节=null;
如果((typeof(T)!=typeof(byte))&&(typeof(T)!=typeof(short))&&(typeof(T)!=typeof(int))&&(typeof(T)!=typeof(long)))
{
抛出(new System.ArgumentException(“此方法仅接受类型[Byte]、[Int16]、[Int32]或[Int64]。,”);
}
if(typeof(T)=typeof(字节))
{
使用(System.Security.Cryptography.RandomNumberGenerator generator=System.Security.Cryptography.RandomNumberGenerator.Create())
{
//从T[]到字节[]的强制转换(隐式或显式)无效。
if(nonzeronly){generator.GetNonZeroBytes(data);}
else{generator.GetBytes(数据);}
}
}
其他的
{
size=System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
字节=新字节[data.Length*size];
使用(System.Security.Cryptography.RandomNumberGenerator generator=System.Security.Cryptography.RandomNumberGenerator.Create())
{
if(nonzeronly){generator.GetNonZeroBytes((byte[])System.Convert.ChangeType(data,typeof(byte[]));}
else{generator.GetBytes((byte[])System.Convert.ChangeType(data,typeof(byte[]));}
}
使用(System.IO.MemoryStream stream=新的System.IO.MemoryStream(字节))
{
使用(System.IO.BinaryReader=new System.IO.BinaryReader(流))
{
//从short/int/long到T的强制转换(隐式或显式)无效。

如果(typeof(T)==typeof(short)){for(inti=0;i我认为你在这里试图变得聪明,并且在这个过程中使事情变得过于复杂。只需编写三种不同的方法:

Int16[] GenerateRandomShorts()
Int32[] GenerateRandomInts()
Int64[] GenerateRandomLongs()

我认为你在这里试图变得聪明,在这个过程中,事情变得过于复杂。只需编写三种不同的方法:

Int16[] GenerateRandomShorts()
Int32[] GenerateRandomInts()
Int64[] GenerateRandomLongs()

您可以这样做,从
int
T

void Foo<T>(T[] data)
{
    ...
    int v = r.Next(255);  // limit to byte.max for simplicity
    data[i] = (T) Convert.ChangeType(v, typeof(T));
}
void Foo(T[]数据)
{
...
int v=r.Next(255);//为了简单起见,限制为byte.max
数据[i]=(T)转换.ChangeType(v,typeof(T));
}

您可以这样做,从
int
T

void Foo<T>(T[] data)
{
    ...
    int v = r.Next(255);  // limit to byte.max for simplicity
    data[i] = (T) Convert.ChangeType(v, typeof(T));
}
void Foo(T[]数据)
{
...
int v=r.Next(255);//为了简单起见,限制为byte.max
数据[i]=(T)转换.ChangeType(v,typeof(T));
}

这里绝对没有理由使用泛型,您所面临的问题是逆流而上的结果

只需使用非泛型重载,并让编译器根据第一个参数的类型选择要使用的重载:

public static void GenerateRandom(byte[] data, bool nonZeroOnly = false)
{
    using (var generator = RandomNumberGenerator.Create())
    {
        if (nonZeroOnly) { generator.GetNonZeroBytes(data); }
        else { generator.GetBytes(data); }
    }
}

public static void GenerateRandom(short[] data, bool nonZeroOnly = false)
{
    var size = sizeof(short);
    var bytes = new byte[data.Length * size];

    GenerateRandom(bytes, nonZeroOnly);

    for (var i = 0; i < data.Length; ++i) {
        data[i] = BitConverter.ToInt16(bytes, i * size);
    }
}
public静态void generateradom(字节[]数据,bool nonzeronly=false)
{
使用(var生成器=RandomNumberGenerator.Create())
{
if(nonzeronly){generator.GetNonZeroBytes(data);}
else{generator.GetBytes(数据);}
}
}
公共静态void generateradom(short[]数据,bool nonzeronly=false)
{
变量大小=sizeof(短);
var bytes=新字节[data.Length*size];
GeneratorDOM(字节,非零);
对于(变量i=0;i

另外两个重载(如最后一个重载)将处理
int
long
这里绝对没有理由使用泛型,而您所面临的问题是逆流而上的结果

只需使用非泛型重载,并让编译器根据第一个参数的类型选择要使用的重载:

public static void GenerateRandom(byte[] data, bool nonZeroOnly = false)
{
    using (var generator = RandomNumberGenerator.Create())
    {
        if (nonZeroOnly) { generator.GetNonZeroBytes(data); }
        else { generator.GetBytes(data); }
    }
}

public static void GenerateRandom(short[] data, bool nonZeroOnly = false)
{
    var size = sizeof(short);
    var bytes = new byte[data.Length * size];

    GenerateRandom(bytes, nonZeroOnly);

    for (var i = 0; i < data.Length; ++i) {
        data[i] = BitConverter.ToInt16(bytes, i * size);
    }
}
public静态void generateradom(字节[]数据,bool nonzeronly=false)
{
使用(var生成器=RandomNumberGenerator.Create())
{
if(nonzeronly){generator.GetNonZeroBytes(data);}
else{generator.GetBytes(数据);}
}
}
公共静态void generateradom(short[]数据,bool nonzeronly=false)
{
变量大小=sizeof(短);
var bytes=新字节[data.Length*size];
GeneratorDOM(字节,非零);
对于(变量i=0;i

另外两个重载(如最后一个重载)将处理
int
long

我认为泛型不是一个好方法。看起来您应该创建3个独立的方法:
GenerateRandomInt32
GenerateRandomInt16
GenerateRandomInt64
。这是我被迫做的,但我我相信一定有办法通过反射来解决这个问题。@James:代码中的两个注释是编译器对非法转换设置停止标志的地方。您可以使用
Convert.ChangeType
,您使用的类型必须实现IConvertible(所有基元类型都可以)。
int size=Marshal.SizeOf(typeof(T));
可以简化小部件的大小。但好主意是创建单独的方法。我不认为泛型是好方法。看起来你应该创建3个单独的方法:
generaterdomint32
generaterdomint16
generaterdomint64
。这是我被迫要做的,但我肯定有必须使用反射来解决这个问题。@James:代码中的两个注释是编译器对非法conv设置停止标志的地方