C#如何获取类型或类型实例对象的大小

电脑杂谈  发布时间:2020-03-27 22:16:39  来源:网络整理

获取类型c#_获取类型c#_python 获取变量类型

原文: C#如何获取类型或类型实例对象的大小

计算类型或类型实例对象时发生异常:

“无法封送为非托管结构;无法计算有意义的大小或偏移量. ”

检查后,我们创建的结构或类都是复杂类型. (更正后,如果成员具有复杂的类型,并且占用了字节,则在运行时会使用Marhsal.SizeOf出现一些变量,这里也是无效的,仅统计非托管资源)

如果您未在其中设置某些成员的布局,则直接设置sizeof()或Marshal.SizeOf(对象),Marshal.SizeOf(类型)将报告此异常.

因此,我们需要根据需要设置成员布局,以便可以正常执行上述sizeof()或Marshal.SizeOf(对象),Marshal.SizeOf(类型).

1. 了解数据结构的布局

数据结构的布局,首先必须了解: (悲伤刷,百度不适合代码格式,或者CNBLOG很好)

//摘要:

//控制导出到非托管代码时对象的布局.

[可序列化]

[ComVisible(true)]

公共枚举LayoutKind

{

//摘要:

//对象的成员以它们导出到非托管内存时出现的顺序排列. 这些成员基于System.Runtime.InteropServices.StructLayoutAttribute.Pack

中指定的软件包

获取类型c#_获取类型c#_python 获取变量类型

//的布局可以不连续.

顺序= 0,

//

//摘要:

///显式控制对象在非托管内存中每个成员的确切位置. 每个成员都必须使用System.Runtime.InteropServices.FieldOffsetAttribute

//指示字段在类型中的位置.

显式= 2,

//

//摘要:

//运行时自动为非托管内存中的对象成员选择适当的布局. 使用此枚举成员定义的对象不能在托管代码之外公开. 尝试这样做将引发异常.

自动= 3,

}

顺序是有序的,但不是连续的. 通常我们使用这个.

显式这没什么用,因为该成员在内存块中的位置是精确定位的.

汽车我对上述“正确的布局”了解不多. 如果将其用于布局,我上面提到的异常将直接出现:

“无法封送为非托管结构;无法计算有意义的大小或偏移量. ”

2. 了解如何布置复杂类型(类属性)

获取类型c#_python 获取变量类型_获取类型c#

要布置复杂的类型,可以使用该类的属性来设置Attribute基类或其派生类. StructLayoutAttribute即可. 他是Attribute的派生类

//摘要:

// StructLayoutAttribute类允许用户控制类或结构的数据字段的物理布局.

[ComVisible(true)]

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,Inherited = false)]

公共密封类StructLayoutAttribute: 属性

从上面的定义描述中,我们可以知道StructLayoutAttribute是我们想要的类属性,“以控制类或结构的数据字段的物理布局”

3. 演示测试:

首先: 自动

[StructLayout(LayoutKind.Auto)]

A级

{

公共短a = 0;

public int b = 0;

公共长c = 0;

}

A a = new A();

python 获取变量类型_获取类型c#_获取类型c#

int asize = Marshal.SizeOf(a.a); //直接抛出异常

int bsize = Marshal.SizeOf(a.b);

int csize = Marshal.SizeOf(a.c);

int allsize = Marshal.SizeOf(a);

MessageBox.Show(string.Format(“ a.Size: [{0}],b.Size: [{1}],c.Size: [{2}],总计: [{3}]” ,asize获取类型c#,bsize,csize,allsize));

第二个: 显式

[StructLayout(LayoutKind.Explicit)] //要使用Explicit,必须对成员的大小或偏移量进行精确设置. 仅汗水,不建议每个成员

A级

{

[FieldOffset(0)] //仅当布局枚举项为LayoutKind.Explicit时才可以使用字段偏移设置

公共短a = 0;

[FieldOffset(2)]

public int b = 0;

[FieldOffset(6)]

公共长c = 0;

}

A a = new A();

获取类型c#_获取类型c#_python 获取变量类型

int asize = Marshal.SizeOf(a.a); //如果没有FieldOffset的成员设置,则会直接引发异常

int bsize = Marshal.SizeOf(a.b);

int csize = Marshal.SizeOf(a.c);

int allsize = Marshal.SizeOf(a);

MessageBox.Show(string.Format(“ a.Size: [{0}],b.Size: [{1}],c.Size: [{2}],总计: [{3}]” ,asize,bsize,csize,allsize));

第三: 顺序

[StructLayout(LayoutKind.Sequential)] //顺序是有序的,但不是连续的. 至于他为什么能够成功获取类型c#,我也希望Daniel指出其内部原理和sizeof配置.

A级

{

公共短a = 0;

public int b = 0;

公共长c = 0;

}

A a = new A();

int asize = Marshal.SizeOf(a.a); //直接成功

int bsize = Marshal.SizeOf(a.b);

int csize = Marshal.SizeOf(a.c);

int allsize = Marshal.SizeOf(a);

MessageBox.Show(string.Format(“ a.Size: [{0}],b.Size: [{1}],c.Size: [{2}],总计: [{3}]” ,asize,bsize,csize,allsize));

如图所示:


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-154653-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...