C#:如何创建类型泛型方法(byte/word/dword)?
我是泛型新手,我在C#中只能找到列表[T]——其他什么都没有C#:如何创建类型泛型方法(byte/word/dword)?,c#,generics,C#,Generics,我是泛型新手,我在C#中只能找到列表[T]——其他什么都没有 这是我必须在C</p>中翻译的C++代码 模板 键入Read() { t型; int s=sizeof(类型); 如果(索引+s>大小) 抛出(std::异常(“错误101”); memcpy(&t,流+索引,s); 指数+=s; 返回t; } 它的名字是这样的 BYTE mode = Read<BYTE>(); DWORD mode1 = Read<DWORD>(); WORD mode2 = Rea
这是我必须在C</p>中翻译的C++代码
模板
键入Read()
{
t型;
int s=sizeof(类型);
如果(索引+s>大小)
抛出(std::异常(“错误101”);
memcpy(&t,流+索引,s);
指数+=s;
返回t;
}
它的名字是这样的
BYTE mode = Read<BYTE>();
DWORD mode1 = Read<DWORD>();
WORD mode2 = Read<WORD>();
字节模式=读取();
DWORD mode1=读取();
WORD mode2=Read();
问题:如何使用C#泛型实现这一点?您正在寻找的签名是:
public class Reader
{
public static T Read<T>()
{
}
}
公共类读取器
{
公共静态T Read()
{
}
}
您需要将其放入一个类型中。它可以是实例或静态成员
编辑: 除了必须显式地传递泛型类型参数之外,它与其他方法一样使用。例如:
byte mode = Reader.Read<byte>()
byte mode=Reader.Read()
这是一个函数模板。您需要一个C#类,但类似于:
public static class Utility
{
public static Type Read<Type>()
{
//Converted code to c# that returns a Type;
}
}
公共静态类实用程序
{
公共静态类型Read()
{
//将代码转换为返回类型的c#;
}
}
您可能希望为此使用约束,例如限制值类型
您可以这样调用函数:
Utility.Read<int>();
Utility.Read();
看看MSDN上的文章。在这之后,它应该是自解释的……< /p> < p>我只想指出,C++实例中包含了全局变量,并且在泛型类型中做得不太好的事情,这里的其他人已经指出如何处理实际的方法签名,而不是移植C++代码。我会重做一些更符合C#better风格的东西
去掉全局变量。
< p>我的C++非常生锈,但看起来你是从流中读取值类型。 您可以将泛型限制为引用类型或值类型,并且可以使用default
关键字初始化空变量
public T Read<T>( Stream input )
where T:struct //forces T to be a value type
{
T returnValue = default(T); //init a return value
int index = input.Position;
//your conversion here
return returnValue;
}
public T读取(流输入)
其中T:struct//强制T为值类型
{
T returnValue=default(T);//初始化一个返回值
int索引=输入位置;
//你的转换在这里
返回值;
}
您最好将流作为参数传入
也要记住,在C++中,这些是模板——您将获得用于所使用的每个类型的代码的副本。这就排除了引用C++中的C++库,因为当C++被编译时,它不一定有C代码要求编译的类型。
在C#中,只有一个类被编译,并且它可以被外部引用。您的代码似乎模仿了该类的、和方法 在不了解全局变量的情况下,很难提供重写。假设流是一个字节数组,下面的代码可以工作
public T Read<T>() where T : struct {
// An T[] would be a reference type, and alot easier to work with.
T[] t = new T[1];
// Marshal.SizeOf will fail with types of unknown size. Try and see...
int s = Marshal.SizeOf(typeof(T));
if (_index + s > _size)
// Should throw something more specific.
throw new Exception("Error 101");
// Grab a handle of the array we just created, pin it to avoid the gc
// from moving it, then copy bytes from our stream into the address
// of our array.
GCHandle handle = GCHandle.Alloc(t, GCHandleType.Pinned);
Marshal.Copy(_stream, _index, handle.AddrOfPinnedObject(), s);
_index += s;
// Return the first (and only) element in the array.
return t[0];
}
public T Read(),其中T:struct{
//T[]将是一种引用类型,并且更易于使用。
T[]T=新的T[1];
//Marshal.SizeOf将失败,类型大小未知。请尝试查看。。。
ints=Marshal.SizeOf(typeof(T));
如果(\u索引+s>\u大小)
//应该抛出更具体的东西。
抛出新异常(“错误101”);
//抓住我们刚刚创建的数组的句柄,固定它以避免gc
//从移动它,然后复制字节从我们的流到地址
//我们的阵型。
GCHandle handle=GCHandle.Alloc(t,GCHandleType.pinted);
Copy(_stream,_index,handle.AddrOfPinnedObject(),s);
_指数+=s;
//返回数组中的第一个(也是唯一的)元素。
返回t[0];
}
我不完全确定数据流来自何处。但是,如果它是非托管指针,则可以执行以下操作
public static T Read<T>(ref IntPtr ptr)
where T : struct {
var size = Marshal.SizeOf(typeof(T));
var value = (T)Marshal.PtrToStructure(ptr, typeof(T));
ptr = new IntPtr(ptr.ToInt64() + size);
return value;
}
公共静态T读(参考IntPtr ptr)
其中T:struct{
var size=Marshal.SizeOf(typeof(T));
var值=(T)Marshal.PtrToStructure(ptr,typeof(T));
ptr=新的IntPtr(ptr.ToInt64()+大小);
返回值;
}
一些用法示例也很好?我想知道如何在Reader类中“返回”某些内容。请提供一个示例,以及一些如何调用它的示例?很好的解决方案(+1)。我想在其中添加一个T:struct
restriction-对于引用类型不应该调用它。
public static T Read<T>(ref IntPtr ptr)
where T : struct {
var size = Marshal.SizeOf(typeof(T));
var value = (T)Marshal.PtrToStructure(ptr, typeof(T));
ptr = new IntPtr(ptr.ToInt64() + size);
return value;
}