C# 在C语言中将'Int32'转换为'T','T[]`转换为'Int32[]`#
我试图编写一个简单的函数,该函数将使用RandomNumberGenerator类根据泛型参数返回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 =
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设置停止标志的地方