Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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#:如何创建类型泛型方法(byte/word/dword)?_C#_Generics - Fatal编程技术网

C#:如何创建类型泛型方法(byte/word/dword)?

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#中只能找到列表[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 = 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;
}