【问题标题】:Changing a variable type and value based on the process architecture根据流程架构更改变量类型和值
【发布时间】:2019-03-23 00:00:51
【问题描述】:

我有两个预定义的结构

Context // x86
Context64 // x64

我正在尝试基于流程架构创建这些结构之一的实例。例如,如果它被编译为 x86,它将创建一个 Context 的实例,如果它被编译为 x64,它将创建一个 Context64 的实例

我无法形成一个语句,该语句将根据程序编译的内容在两个实例之间进行交换

到目前为止,我已经尝试了以下方法

var compiledAsx64 = Environment.Is64BitProcess;

var context = compiledAsx64 ? new Context64() : new Context();

还有

var compiledAsx64 = Environment.Is64BitProcess;

dynamic context = compiledAsx64 ? new Context64() : new Context();

但是,两者都返回错误,表明两者之间没有隐式转换

我试图避免产生多个变量。这可能吗?如果可以,我该如何实现?

【问题讨论】:

  • 请问ContextContext64 结构是什么?
  • 唯一可以包含两者的变量类型是object,然后您将不断地装箱/拆箱以使用它。如果它们是,那么可能会有一些继承技巧。
  • 问题与处理器架构完全无关。您试图将变量设置为不同的类型
  • 根据您需要此功能的位置,您可以只引入一个编译器开关,例如#IF x86 var a = Context #ELSE var a = Context64
  • 没有一个结构类型的变量可以同时保存这两种类型的值,您需要使用多个变量或忍受将它们装箱成对象的后果。对于后者,您可以使用接口,将它们转换为类,或者使用动态的、不同的选择、不同的性能特征。

标签: c#


【解决方案1】:

将任一类型转换为目标类型,您就可以开始了。

dynamic context = compiledAsx64 ? (dynamic)new Context64() : new Context();

为什么?每the documentation

first_expression 和 second_expression 的类型必须相同,或者必须存在从一种类型到另一种类型的隐式转换。

不过,更好的方法是使用#if,这样您就可以获得类型安全。看到这个问题:How to use #if to decide which platform is being compiled for。所以你的代码看起来像这样:

#if X64
var context = new Context64();
#else
var context = new Context();
#endif

【讨论】:

  • #if X64 部分仅在编译期间使用,前提是您创建的任何 CPU 应用程序可以在 64 位操作系统上以 64 位运行,在 32 位操作系统上以 32 位运行。位操作系统,您仍然需要在编译时选择使用哪个结构,或者您还必须交付应用程序的 32 位和 64 位副本。
【解决方案2】:

编译器需要确定返回条件运算符的通用类型 (?…:)。将结果分配给dynamic 没有区别。

保留条件运算符的最简单方法可能是 Context64Content 实现一个通用接口。

使用语句更容易...

dynamic context;
if (Environment.Is64BitProcess) {
  context = new Context64();
} else {
  context = new Context();
}

【讨论】:

  • 上下文是结构体,我不建议为了使用条件运算符而实现通用接口。
  • @Reniuz 别忘了dynamic 真的是object 加上元数据和反射:即。更高的开销。 “最佳”答案取决于 Context/Context64 的用途。
  • 同意,这取决于用例。
猜你喜欢
  • 2019-04-01
  • 1970-01-01
  • 2011-03-25
  • 2017-01-31
  • 1970-01-01
  • 2011-10-29
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多