当我尝试从现有应用程序编写C#应用程序但在Delphi中开发时, 非常艰难,但管理了一些如何,但现在我遇到了一个问题......
Delphi代码包含以下代码:
type
TFruit = record
name : string[20];
case isRound : Boolean of // Choose how to map the next section
True :
(diameter : Single); // Maps to same storage as length
False :
(length : Single; // Maps to same storage as diameter
width : Single);
end;
即。一个变体记录(里面有case
语句),因此也构建了记录及其大小。
另一方面,我试图在C#struct中做同样的事情,但还没有成功,我希望有人能在这里帮助我。
所以,请告诉我是否有任何方法可以在C#中实现这一点。
提前谢谢....
答案 0 :(得分:5)
您可以使用显式结构布局来复制此Delphi变体记录。但是,我不会打扰,因为您似乎不太可能希望分配到diameter
并分配给length
,反之亦然。 Delphi记录声明看起来像是20世纪90年代中期的Delphi编码风格。现代Delphi代码很少以这种方式编写。
我会这样做:
struct Fruit
{
string name;
bool isRound;
float diameter; // only valid when isRound is true
float length; // only valid when isRound is false
float width; // only valid when isRound is false
}
更优雅的选项是具有每个struct字段属性的类。如果访问isRound
的值无效,您可以安排3个浮点数的属性getter和setter引发异常。
答案 1 :(得分:1)
也许这会成功吗?
这不是复制粘贴解决方案,请注意,根据Delphi结构的声明和/或对齐方式,可能需要更改偏移量和数据大小。
[StructLayout(LayoutKind.Explicit)]
unsafe struct Fruit
{
[FieldOffset(0)] public fixed char name[20];
[FieldOffset(20)] public bool IsRound;
[FieldOffset(21)] public float Diameter;
[FieldOffset(21)] public float Length;
[FieldOffset(25)] public float Width;
}
答案 2 :(得分:1)
这取决于你想要做什么。
如果您只想尝试制作相应的结构,请查看David Heffernan的答案。现在几乎没有理由将两个字段映射到彼此之上,除非它们真正代表相同的东西。 (比如说,单个项目或数组中的相同项目。)
如果你真的想要分享文件,你需要看看ananthonline的答案,但是它有一个问题,它足够大我不能把它放在评论中:
不仅存在Unicode问题,而且Delphi短串在C#中没有相应的结构,因此不可能简单地在其上面映射字段。
该字符串[20]实际上包含 21 字节,一个字节长度的代码,然后是20个字符的数据。您必须遵守长度代码,因为无法保证超出指定长度的内容 - 您可能会在那里找到垃圾。 (提示:如果要将记录写入磁盘,则在将新数据放入其中之前始终删除该字段。这使得在调试时更容易检查磁盘上的文件。)
因此,您需要声明两个字段并编写代码以在两端处理它。
由于你必须这样做,我会更进一步,编写代码来处理其余部分,以便根本不需要不安全的代码。