Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.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
如何使用<;使方法返回任意结构;T>;C#中的魔法?_C# - Fatal编程技术网

如何使用<;使方法返回任意结构;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