Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.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#Struct没有无参数构造函数?看看我需要完成什么_C#_Dll_Constructor_Struct_Dllimport - Fatal编程技术网

C#Struct没有无参数构造函数?看看我需要完成什么

C#Struct没有无参数构造函数?看看我需要完成什么,c#,dll,constructor,struct,dllimport,C#,Dll,Constructor,Struct,Dllimport,我正在使用结构传递到非托管DLL- [StructLayout(LayoutKind.Sequential)] public struct valTable { public byte type; public byte map; public byte spare1; public byte spare2; public int par;

我正在使用结构传递到非托管DLL-

[StructLayout(LayoutKind.Sequential)]
        public struct valTable
        {
            public byte type;
            public byte map;
            public byte spare1;
            public byte spare2;
            public int par;
            public int min;
            public byte[] name;
            public valTable()
            {
                name = new byte[24];
            }
        }
上面的代码不会编译,因为VS2005会抱怨“结构不能包含显式的无参数构造函数”。为了将这个结构传递给我的DLL,我必须传递一个结构数组,如so
valTable[]val=newvaltable[281]

我想做的是,当我说
new
时,调用构造函数,它创建一个字节数组,就像我试图演示的那样,因为DLL在每个维度中寻找大小为24的字节数组


我怎样才能做到这一点呢?

对于你需要做的事情,我认为你真的需要一门课。默认情况下,结构已经实现了无参数构造函数,这就是您无法定义另一个构造函数的原因。

结构构造函数与类构造函数类似,但有以下区别:

  • 结构不能包含显式 无参数构造函数。结构 成员将自动初始化 设置为其默认值
  • 结构不能有初始值设定项 形式为:base(参数列表)
这意味着

A default(parameterless) constructor for a struct could set different
values than the all-zeroed state which would be unexpected behavior. The
.Net Runtime therefore prohabits default constructors for struct.
绕过此场景的典型方法是创建一个静态方法 这将创建您的新实例,以您想要的方式初始化它,然后 归还它。这是在.NET中初始化结构的方法 具有特定的值


ref;

不是最干净的修复方法,但您可以只添加一个参数而不使用它

[StructLayout(LayoutKind.Sequential)]
    public struct valTable
    {
        public byte type;
        public byte map;
        public byte spare1;
        public byte spare2;
        public int par;
        public int min;
        public byte[] name;
        public valTable(int x)
        {
            name = new byte[24];
        }
    }
您可以使用-我想您确实希望使用-以便在结构中“内联”获取数据(而不是在别处引用数组)

不过,您还需要将结构声明为不安全


请注意,任何需要调用静态方法或提供任何类型的自定义构造函数的“解决方案”都会失败,因为您的明确目标是能够创建这些结构的数组。

我建议编写此代码

[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
    public byte type;
    public byte map;
    public byte spare1;
    public byte spare2;
    public int par;
    public int min;
    public byte[] name;

    static public valTable Create()
    {
        valTable vT = new valTable();
        vT.name = new byte[24];
        return vT;
    }
}
在此基础上,您可以创建一个静态方法来执行构造函数的工作,如下所示:

[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
    public byte type;
    public byte map;
    public byte spare1;
    public byte spare2;
    public int par;
    public int min;
    public byte[] name;
    public valTable()

    public static valTable NewTable()
    {
        valTable tbl = new valTable();
        tbl.name = new byte[24];
        return tbl;
    }
}

您将看到.NET Framework中的类已经遵循此模式。我立刻想到了。可能还有其他的。

他正在将此结构传递给dll。这是一个错误的答案。。它应该被删除。我投了-1票,因为它促进的代码是误导性的,不太符合逻辑。有更干净的方法可以做到这一点(比如使用静态创建方法)。虚拟参数有点烦人,但并不未知。例如,正常的IDisposable模式有一个伪参数(如果类没有终结器,则永远不应使用“false”值调用其Dispose方法)。请同意。解决方法会产生其他问题,例如buffer.blockcopy和byte[].copyto都会在固定字段上失败。语言限制对于避免常见错误是有意义的,但是“正确”的方法不应该要求编写大量的变通代码。我不知道
fixed
关键字可以这样使用,我已经多次想要这样的东西。我…我…我爱你,伙计@杰弗里:不能说我自己用过它,但我必须为C#Depth:)@Mitch:谢谢,我在答案中添加了链接。@Jon Skeet-我有C#Depth,我读过并喜欢它。不知怎的,我错过了那部分。我曾经在一个结构中放入九个整数变量,并使用switch语句模拟数组访问,只是为了得到一个堆栈分配的数组@杰弗里:小心点。很容易出错。看看有什么想法。坦白地说,很多时候我可能会使用你的九整数解。:-)这可能是我的第一个选择,但Jon Skeet的似乎很简单为什么有
public valTable()
?net框架对值类型做了两个基本假设:(1)创建任何类型的数组时,除了清空内存外,无需做任何事情;(2) 复制任何类型的字段或变量时,除了复制字节外,无需执行任何操作。一个相关的概念是,执行对象的浅层克隆同样应该什么也不做,只克隆其中任何值类型字段的字节。
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
    public byte type;
    public byte map;
    public byte spare1;
    public byte spare2;
    public int par;
    public int min;
    public byte[] name;
    public valTable()

    public static valTable NewTable()
    {
        valTable tbl = new valTable();
        tbl.name = new byte[24];
        return tbl;
    }
}