7

有没有办法可以有条件地将属性应用于结构?

如果机器是32bit我想应用这个属性

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

如果机器是64bit我想应用这个属性

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

或者,我可以在属性中替换一个值...

32 位(包 = 2)

[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]

64 位(包 = 8)

[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]

我尝试使用此示例,但它用于自定义属性,而不是现有属性。

更新:

  • 我想介绍“任何 CPU”
  • 该属性用于SHFILEOPSTRUCT,取决于处理器使用或。
  • 我不想编译两个版本。
4

3 回答 3

6

好问题。

我首先想到的答案是预处理器指令和 32 位和 64 位编译程序集。您可以使用相同的代码,甚至是相同的项目,只需根据目标系统以两种方式构建和部署它:

#ifdef Bit32
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]
#endif
#ifdef Bit64
[StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
#endif

这将需要根据目标架构为您的项目定义 Bit32 和 Bit64 编译常量,并且可能会构建您的应用程序两次。

如果您想在运行时执行此操作,我认为除非您在运行时动态发出整个类,否则这是不可能的。属性可能只有常量数据,它们不能在运行时有条件地应用(预处理器指令在编译时运行,而不是运行时)。

我能想到的唯一另一种方法是将类定义复制到两个命名空间中,并根据 Environment.Is64BitOperatingSystem 属性有条件地使用其中一个。您可以使用该属性有条件地控制您实例化哪个类,或者您选择哪种创建策略(使用哪种工厂方法或相关模式),但您不能在运行时有条件地控制属性;它们的信息作为元数据静态编译到程序集清单中。运行时本身特别使用此属性来定义它如何将对象的成员存储为堆数据,并且您永远不会真正在用户代码中查找此属性并使用它来定义行为(因此忽略或指定条件 Pack运行时的值)。

于 2012-09-13T16:26:26.770 回答
1

创建两个不同的构建目标(一个用于 32 位,一个用于 64 位),为每个目标添加一个条件编译符号(一个为 x86,另一个为 x86_64)并#ifdef在结构定义周围使用 's。

于 2012-09-13T16:26:56.543 回答
0

我不认为你能做到这一点。只需有 2 个结构,并提供一种将两者转换为共享结构或类以进行处理的方法......

注意:您要求的功能非常奇怪(基于运行时发生的 JIT 类型的不同显式结构布局)。在大多数情况下,这用于匹配某些著名的固定协议的字节的物理布局,而与应用程序的比特性无关。您可以将您的案例视为 x86/x64 案例有 2 个不同的协议/互操作,并对 2 个结构感到满意。

于 2012-09-13T16:23:39.083 回答