C# 中的 Lazarus 指针类型
Lazarus pointer type in C#
我正在尝试将 lazarus 项目转换为 c#。到目前为止一切都很好,但我现在遇到了问题。
有这样一个代码:
xActor = record
Id: integer;
Value: integer;
Name: ansistring;
Height: integer;
Gender : Boolean;
Position : byte;
end;
我在 C# 中将其创建为一个结构。然而,在这段代码之后我看到了这样的东西
PxActor = ^xActor;
我研究了一下,发现这意味着创建一个包含 xActor 指针的类型,但我可能错了。
然后我在代码中看到了一个比较有意思的记录
yActor = packed record
Actor: array [1..9] of PxActor;
end;
此时我不知道如何将它们转换为 c#,因为我不知道 PxActor = ^xActor;
是什么意思。
提前致谢
C# 有两种不同类型的对象 - 引用类型和值类型。
您的代码混合了两者(在 C/Pascal 中很常见),因为您有一个 C# 值类型(struct
xActor)和一个引用相同的引用类型类型(指针 PxActor
),这在 C# 中相当是不可能的。
但是,有一些方法可以模拟类似的行为。但首先,您必须考虑这应该工作的逻辑方式。也许这只是一个性能调整(例如,使用 PxActor
的数组而不是 xActor
,因为你想节省额外的内存,而不是将整个 xActor
结构放在那里)。也许您更希望从多个地方获得相同的值,并且是可变的。
这两种情况通常都可以通过简单地使 xActor
成为 class
来解决 - 在 C# 中,这意味着它将始终是引用类型(在 [=67= 中没有意义) ],但 C# 和类似语言中的主要对象)。但是,您需要手动检查每个使用 xActor
或 PxActor
类型的地方,并确保 value/reference 语义仍然相同。这可能会导致一些难以发现的错误,具体取决于原始代码。
另一种选择是创建包装器 class。因此,您将保留 struct xActor
,但您还将创建一个 class PxActor
,它将有一个 xActor
字段。这不是 Pascal 指针的精确模拟,但如果你小心的话,它可以以类似的方式使用。主要区别在于您无法在某处捕获指向现有值的指针 - 您只能创建一个新的 PxActor
,它拥有 xActor
的 copy .访问 PxActor
实例的任何人也将使用相同的 xActor
实例,但任何时候您存储 xActor
本身,它都是一个新副本。但在最简单的情况下,您可以将 xActor
和后续 @
的手动分配替换为 new PxActor()
,并将任何 variable^.Gender
访问 variable.ActorField.Gender
.
就在重构过程中,也可以使用 C# 的指针。与 C/Pascal 相比,它们有点受限,但它们可能适用于您的情况。除了 string
值。然而,指针有很多成本,所以除非它们是一个好主意,否则你不想使用它们,但事实并非如此:)
换句话说,1:1 从 Pascal 到 C# 的转换通常不是一个好主意。您需要弄清楚所有内容背后的语义是什么。查找给定类型的 所有 用法将是一项繁重的工作。逐行翻译很容易让你陷入困境。 C# 是一种非常安全的语言,而 CLR 非常擅长确保每个人都可以相互交谈,但这也意味着在 value/reference 传递和类似内容方面存在一些差异。现在,IIRC,Pascal 默认具有值语义,所以使用 struct
和类似的东西在 C# 中应该也能很好地工作。不过,您必须分析指针的任何使用。有时,您可以使用 C# 的 out
或 ref
而不是指针 - 去吧。但是你这里的情况并不完全是这样——它是一个存储在另一种类型中的指针,而不仅仅是作为参数传递。然而,这仍然没有告诉我们它在实践中应该如何工作——也许这只是解决 Pascal 限制的一种方法;也许你会在 C# 中使用 List<xActor>
而不是 array of PxActor
.
当然,这通常是最好的选择。在可能的情况下,使用惯用的 C#,而不是仅仅尝试在 C# 中编写 Pascal 代码。虽然有很多相似之处,但也有很多差异会影响您,使您的工作比必要的更难。找到 List<SomeType>
比 array of PSomeType
更有效的地方。找出可以用ref
和out
代替PSomeType
的地方。找到 struct
有意义的地方,以及 class
更好的地方。这适用于许多可能毁了你一天的细微差异,所以随着时间的推移你可能会发现很多问题,但这是一个旅程 :)
我正在尝试将 lazarus 项目转换为 c#。到目前为止一切都很好,但我现在遇到了问题。
有这样一个代码:
xActor = record
Id: integer;
Value: integer;
Name: ansistring;
Height: integer;
Gender : Boolean;
Position : byte;
end;
我在 C# 中将其创建为一个结构。然而,在这段代码之后我看到了这样的东西
PxActor = ^xActor;
我研究了一下,发现这意味着创建一个包含 xActor 指针的类型,但我可能错了。
然后我在代码中看到了一个比较有意思的记录
yActor = packed record
Actor: array [1..9] of PxActor;
end;
此时我不知道如何将它们转换为 c#,因为我不知道 PxActor = ^xActor;
是什么意思。
提前致谢
C# 有两种不同类型的对象 - 引用类型和值类型。
您的代码混合了两者(在 C/Pascal 中很常见),因为您有一个 C# 值类型(struct
xActor)和一个引用相同的引用类型类型(指针 PxActor
),这在 C# 中相当是不可能的。
但是,有一些方法可以模拟类似的行为。但首先,您必须考虑这应该工作的逻辑方式。也许这只是一个性能调整(例如,使用 PxActor
的数组而不是 xActor
,因为你想节省额外的内存,而不是将整个 xActor
结构放在那里)。也许您更希望从多个地方获得相同的值,并且是可变的。
这两种情况通常都可以通过简单地使 xActor
成为 class
来解决 - 在 C# 中,这意味着它将始终是引用类型(在 [=67= 中没有意义) ],但 C# 和类似语言中的主要对象)。但是,您需要手动检查每个使用 xActor
或 PxActor
类型的地方,并确保 value/reference 语义仍然相同。这可能会导致一些难以发现的错误,具体取决于原始代码。
另一种选择是创建包装器 class。因此,您将保留 struct xActor
,但您还将创建一个 class PxActor
,它将有一个 xActor
字段。这不是 Pascal 指针的精确模拟,但如果你小心的话,它可以以类似的方式使用。主要区别在于您无法在某处捕获指向现有值的指针 - 您只能创建一个新的 PxActor
,它拥有 xActor
的 copy .访问 PxActor
实例的任何人也将使用相同的 xActor
实例,但任何时候您存储 xActor
本身,它都是一个新副本。但在最简单的情况下,您可以将 xActor
和后续 @
的手动分配替换为 new PxActor()
,并将任何 variable^.Gender
访问 variable.ActorField.Gender
.
就在重构过程中,也可以使用 C# 的指针。与 C/Pascal 相比,它们有点受限,但它们可能适用于您的情况。除了 string
值。然而,指针有很多成本,所以除非它们是一个好主意,否则你不想使用它们,但事实并非如此:)
换句话说,1:1 从 Pascal 到 C# 的转换通常不是一个好主意。您需要弄清楚所有内容背后的语义是什么。查找给定类型的 所有 用法将是一项繁重的工作。逐行翻译很容易让你陷入困境。 C# 是一种非常安全的语言,而 CLR 非常擅长确保每个人都可以相互交谈,但这也意味着在 value/reference 传递和类似内容方面存在一些差异。现在,IIRC,Pascal 默认具有值语义,所以使用 struct
和类似的东西在 C# 中应该也能很好地工作。不过,您必须分析指针的任何使用。有时,您可以使用 C# 的 out
或 ref
而不是指针 - 去吧。但是你这里的情况并不完全是这样——它是一个存储在另一种类型中的指针,而不仅仅是作为参数传递。然而,这仍然没有告诉我们它在实践中应该如何工作——也许这只是解决 Pascal 限制的一种方法;也许你会在 C# 中使用 List<xActor>
而不是 array of PxActor
.
当然,这通常是最好的选择。在可能的情况下,使用惯用的 C#,而不是仅仅尝试在 C# 中编写 Pascal 代码。虽然有很多相似之处,但也有很多差异会影响您,使您的工作比必要的更难。找到 List<SomeType>
比 array of PSomeType
更有效的地方。找出可以用ref
和out
代替PSomeType
的地方。找到 struct
有意义的地方,以及 class
更好的地方。这适用于许多可能毁了你一天的细微差异,所以随着时间的推移你可能会发现很多问题,但这是一个旅程 :)