如何使用<;使方法返回任意结构;T>;C#中的魔法?
标题概括了这一点。我想打个电话如何使用<;使方法返回任意结构;T>;C#中的魔法?,c#,C#,标题概括了这一点。我想打个电话 Foo f = getStruct<Foo>(..) 该函数将.raw指针和扇区传递给另一个函数,该函数从磁盘加载该扇区,然后逐字节将内容复制回.raw 通过这种方式,我可以创建一个任意结构,并从磁盘快速简单地填充它。我知道这不是很友好,但还有其他外部依赖需要它 Thnx 我不知道这是否是您想要的,但您可以创建一个类似这样的通用方法: public static T GetStruct<T>() where T : struct //i
Foo f = getStruct<Foo>(..)
该函数将.raw指针和扇区传递给另一个函数,该函数从磁盘加载该扇区,然后逐字节将内容复制回.raw
通过这种方式,我可以创建一个任意结构,并从磁盘快速简单地填充它。我知道这不是很友好,但还有其他外部依赖需要它
Thnx 我不知道这是否是您想要的,但您可以创建一个类似这样的通用方法:
public static T GetStruct<T>() where T : struct //if T has to be struct
{
return new T();
//or return Activator.CreateInstance<T>();
}
但是如果您有Foo
的子类型,那么将函数设置为泛型是有意义的。大概是这样的:
public T getStruct<T>(UInt32 sector) where T : Foo
{
T foo = new T();
for (int i=0; i<100; i++) foo.raw=0;
return foo;
}
public T getStruct(UInt32扇区),其中T:Foo
{
T foo=新的T();
对于(int i=0;i我不知道这是否是您所寻找的,但您可以创建一个类似以下的通用方法:
public static T GetStruct<T>() where T : struct //if T has to be struct
{
return new T();
//or return Activator.CreateInstance<T>();
}
但是如果您有Foo
的子类型,那么将函数设置为泛型是有意义的。例如:
public T getStruct<T>(UInt32 sector) where T : Foo
{
T foo = new T();
for (int i=0; i<100; i++) foo.raw=0;
return foo;
}
public T getStruct(UInt32扇区),其中T:Foo
{
T foo=新的T();
对于(int i=0;i您需要创建接口:
public interface IFoo
{
int Raw { get; set; }
}
public struct Foo:IFoo
{
[System.Runtime.InteropServices.FieldOffset(0)] public fixed byte raw[512];
public int Raw { get{return raw;} set{raw = value;} }
}
您的所有结构都必须实现此接口:
public interface IFoo
{
int Raw { get; set; }
}
public struct Foo:IFoo
{
[System.Runtime.InteropServices.FieldOffset(0)] public fixed byte raw[512];
public int Raw { get{return raw;} set{raw = value;} }
}
并创建通用方法:
public static T GetStructs<T>(UInt32 sector) where T : struct, IFoo
{
var foo = new T {Raw = new int[sector]};
for (var i = 0; i < 100; i++)
{
foo.Raw[i] = 0;
}
return foo;
}
公共静态T GetStructs(UInt32扇区),其中T:struct,IFoo
{
var foo=newt{Raw=newint[sector]};
对于(变量i=0;i<100;i++)
{
foo.Raw[i]=0;
}
返回foo;
}
要调用它,请使用以下代码:
var foo = getStructs<Foo>(32);
var foo=getStructs(32);
您需要创建界面:
public interface IFoo
{
int Raw { get; set; }
}
public struct Foo:IFoo
{
[System.Runtime.InteropServices.FieldOffset(0)] public fixed byte raw[512];
public int Raw { get{return raw;} set{raw = value;} }
}
您的所有结构都必须实现此接口:
public interface IFoo
{
int Raw { get; set; }
}
public struct Foo:IFoo
{
[System.Runtime.InteropServices.FieldOffset(0)] public fixed byte raw[512];
public int Raw { get{return raw;} set{raw = value;} }
}
并创建通用方法:
public static T GetStructs<T>(UInt32 sector) where T : struct, IFoo
{
var foo = new T {Raw = new int[sector]};
for (var i = 0; i < 100; i++)
{
foo.Raw[i] = 0;
}
return foo;
}
公共静态T GetStructs(UInt32扇区),其中T:struct,IFoo
{
var foo=newt{Raw=newint[sector]};
对于(变量i=0;i<100;i++)
{
foo.Raw[i]=0;
}
返回foo;
}
要调用它,请使用以下代码:
var foo = getStructs<Foo>(32);
var foo=getStructs(32);
您需要一个结构工厂
在这里,我使用了接口和包含的结构的组合。如果固定字节结构是公共的,那么我将为此创建一个结构,并将其包含在我定义的所有结构中。如果需要,您还可以设置一个接口以从泛型方法获得访问权限
初始化仍然由Activator
对象处理,我确保通过调用RawBuffer
中的Initialize()
方法来初始化原始字节
例如,我初始化了两个不同的结构,并计算了完成操作所需的时间
public interface IBlock
{
RawBuffer Raw { get; }
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct RawBuffer
{
public const int Count = 512;
public const int Size = sizeof(byte) * Count;
public fixed byte raw[Count];
public void Initialize()
{
fixed (byte* ptr = raw)
{
for (int i = 0; i < Count; i++)
{
ptr[i] = 0;
}
}
}
}
[StructLayout(LayoutKind.Explicit, Size = RawBuffer.Size)]
public unsafe struct RunBlock_t : IBlock
{
[FieldOffset(0)] public RawBuffer raw;
[FieldOffset(0)] public UInt16 run_id;
[FieldOffset(2)] public UInt16 magic;
[FieldOffset(510)] public UInt16 checksum;
public RunBlock_t(UInt32 sector)
{
raw.Initialize();
run_id = 0;
magic = 0;
checksum = 0;
}
public RawBuffer Raw { get { return raw; } }
}
[StructLayout(LayoutKind.Explicit, Size=RawBuffer.Size)]
public unsafe struct RunBlock_s : IBlock
{
[FieldOffset(0)] public RawBuffer raw;
[FieldOffset(0)] public UInt16 run_id;
[FieldOffset(2)] public UInt32 soup;
[FieldOffset(510)] public UInt16 checksum;
public RunBlock_s(UInt32 sector)
{
raw.Initialize();
run_id = 0;
soup = 0;
checksum = 0;
}
public RawBuffer Raw { get { return raw; } }
}
class Program
{
public static T Factory<T>(UInt32 sector)
where T : struct, IBlock
{
return (T)Activator.CreateInstance(typeof(T), sector);
}
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
var A = Factory<RunBlock_t>(0x20);
long tic = sw.ElapsedTicks;
Console.WriteLine("Initilized {0} in {1} cycles", A.GetType().Name, tic);
// Initilized RunBlock_t in 1524 cycles
sw = Stopwatch.StartNew();
var B = Factory<RunBlock_s>(0x40);
tic = sw.ElapsedTicks;
Console.WriteLine("Initilized {0} in {1} cycles", B.GetType().Name, tic);
// Initilized RunBlock_s in 722 cycles
}
}
公共接口IBlock
{
RawBuffer原始{get;}
}
[StructLayout(LayoutKind.Sequential)]
公共不安全结构RawBuffer
{
公共常数整数计数=512;
公共常量int Size=sizeof(字节)*计数;
公共固定字节原始[计数];
公共无效初始化()
{
固定(字节*ptr=raw)
{
for(int i=0;i
您需要一个结构工厂
在这里,我使用了接口和包含的结构的组合。如果固定字节结构是公共的,那么我将为此创建一个结构,并将其包含在我定义的所有结构中。如果需要,您还可以设置一个接口以从泛型方法获得访问权限
初始化仍然由Activator
对象处理,我确保通过调用RawBuffer
中的Initialize()
方法来初始化原始字节
例如,我初始化了两个不同的结构,并计算了完成操作所需的时间
public interface IBlock
{
RawBuffer Raw { get; }
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct RawBuffer
{
public const int Count = 512;
public const int Size = sizeof(byte) * Count;
public fixed byte raw[Count];
public void Initialize()
{
fixed (byte* ptr = raw)
{
for (int i = 0; i < Count; i++)
{
ptr[i] = 0;
}
}
}
}
[StructLayout(LayoutKind.Explicit, Size = RawBuffer.Size)]
public unsafe struct RunBlock_t : IBlock
{
[FieldOffset(0)] public RawBuffer raw;
[FieldOffset(0)] public UInt16 run_id;
[FieldOffset(2)] public UInt16 magic;
[FieldOffset(510)] public UInt16 checksum;
public RunBlock_t(UInt32 sector)
{
raw.Initialize();
run_id = 0;
magic = 0;
checksum = 0;
}
public RawBuffer Raw { get { return raw; } }
}
[StructLayout(LayoutKind.Explicit, Size=RawBuffer.Size)]
public unsafe struct RunBlock_s : IBlock
{
[FieldOffset(0)] public RawBuffer raw;
[FieldOffset(0)] public UInt16 run_id;
[FieldOffset(2)] public UInt32 soup;
[FieldOffset(510)] public UInt16 checksum;
public RunBlock_s(UInt32 sector)
{
raw.Initialize();
run_id = 0;
soup = 0;
checksum = 0;
}
public RawBuffer Raw { get { return raw; } }
}
class Program
{
public static T Factory<T>(UInt32 sector)
where T : struct, IBlock
{
return (T)Activator.CreateInstance(typeof(T), sector);
}
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
var A = Factory<RunBlock_t>(0x20);
long tic = sw.ElapsedTicks;
Console.WriteLine("Initilized {0} in {1} cycles", A.GetType().Name, tic);
// Initilized RunBlock_t in 1524 cycles
sw = Stopwatch.StartNew();
var B = Factory<RunBlock_s>(0x40);
tic = sw.ElapsedTicks;
Console.WriteLine("Initilized {0} in {1} cycles", B.GetType().Name, tic);
// Initilized RunBlock_s in 722 cycles
}
}
公共接口IBlock
{
RawBuffer原始{get;}
}
[StructLayout(LayoutKind.Sequential)]
公共不安全结构RawBuffer
{
公共常数整数计数=512;
公共常量int Size=sizeof(字节)*计数;
公共固定字节原始[计数];
公共无效初始化()
{
固定(字节*ptr=raw)
{
for(int i=0;i