[英]C#: How to make a Type generic method(byte/word/dword)?
我是泛型新手,我在C#中只能找到List [T]-没有别的。
这是我必须在C#中翻译的C ++代码
template <class type>
type Read()
{
type t;
int s = sizeof(type);
if(index + s > size)
throw(std::exception("error 101"));
memcpy(&t, stream + index, s);
index += s;
return t;
}
像那样
BYTE mode = Read<BYTE>();
DWORD mode1 = Read<DWORD>();
WORD mode2 = Read<WORD>();
问题:如何使用C#泛型呢?
这是一个功能模板。 您需要使用C#编写的类,但是类似:
public static class Utility
{
public static Type Read<Type>()
{
//Converted code to c# that returns a Type;
}
}
您可能需要为此使用约束,例如限制为值类型。
您可以这样调用函数:
Utility.Read<int>();
您的代码似乎模仿BinaryReader类的ReadInt16 , ReadInt32和ReadInt64方法。
没有全局变量的知识就很难进行重写。 假设流是字节数组,则以下代码将起作用。
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 class Reader
{
public static T Read<T>()
{
}
}
您需要将其放入类型中。 它可以是实例或静态成员。
编辑:
它与其他任何方法一样使用,除了必须显式传递泛型类型参数。 例如:
byte mode = Reader.Read<byte>()
看看MSDN上的C#泛型简介一文。 在那之后应该不言自明...
我只想指出,您的C ++示例充满了全局变量,并且在泛型类型上做的工作并不很好,这里的其他人指出了如何处理实际的方法签名,但是没有移植该C ++代码,我会重新设计一些更适合C#风格的东西。
摆脱全局变量。
我的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;
}
您最好也将流作为参数传递。
还请记住,在C ++中,这些是模板-您将获得为每种使用的类型编译的代码的副本。 这排除了从C#引用C ++库的可能性,因为在编译C ++时,它不一定具有C#代码要求编译的类型。
在C#中,仅编译了一个类,并且可以在外部引用它。
我不确定您的数据流来自何处。 但是,如果它是非托管指针,则可以执行以下操作。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.