- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在特定的上下文中,我需要管理约束值。简化;假设我需要将值限制为字符串或 64 位整数。
为了这个目的;我正在考虑声明一种结构类型,其中一个字段用于存储值的类型,一个字段用于实际值。
在这个简化的例子中,类型字段可能会被省略,因为我们可以通过它们的 CLR 类型来区分字符串和整数。然而;我需要类型字段用于其他目的(多个“约束值类型”可以由单个 CLR 类型表示)。
直接的方法:
public struct MyValue
{
private object _value;
private MyValueType _type;
public string String
{
get
{
// todo: check type
return (string)_value;
}
set
{
// todo: validate value
_type = MyValueType.String;
_value = value;
}
}
public long Int64
{
get
{
// todo: check type
return (long)_value;
}
set
{
// todo: validate value
_type = MyValueType.Int64;
_value = value;
}
}
}
但是,这种方法需要一些“额外的”IL 指令:
castclass
指令来从对象转换为字符串。unbox.any
指令来从对象转换为 long。box
指令来将 long 转换为 object。这个结构的目的是强制约束,所以当它获取或设置一个值时,就知道它是正确的类型。
因此我正在考虑使用 FieldOffset属性。像这样:
[StructLayout(LayoutKind.Explicit)]
public struct MyValue
{
[FieldOffset(0)]
private string _string;
[FieldOffset(0)]
private long _int64;
[FieldOffset(8)]
private MyValueType _type;
public string String
{
get
{
// todo: check type
return _string;
}
set
{
// todo: validate value
_type = MyValueType.String;
_string = value;
}
}
public long Int64
{
get
{
// todo: check type
return _int64;
}
set
{
// todo: validate value
_type = MyValueType.Int64;
_int64 = value;
}
}
}
使用这种方法,没有额外的装箱、拆箱或转换说明。这让我觉得这种方法更好。
问题是:使用显式结构布局和字段偏移属性有什么缺点吗?
也许 JIT 编译器会因为某种原因而窒息?
在实际代码中;该结构将是不可变的。这些字段将是只读的,并且不会有任何 setter 。
首先,我不认为这会有什么不同,因为这或多或少意味着 setter 将移至构造函数中,每个值类型一个。
但是;编译器要求所有结构成员都由构造函数初始化——而不考虑它们具有相同的字段偏移量。
我需要做这样的事情:
public MyValue(string value)
{
// todo: validate value
_int64 = 0; // just to satisfy the compiler
_string = value;
_type = MyValueType.String;
}
public MyValue(long value)
{
// todo: validate value
_string = null; // just to satisfy the compiler
_int64 = value;
_type = MyValueType.Int64;
}
这意味着第二种方法也需要“额外的”IL 指令。对于“默认”每个不会使用的字段,还有三个额外的说明。
例如:设置_string = null
产生ldarg.0
、ldnull
和stfld
。
这些额外的指令完全是浪费。如果我添加额外的字段,情况会变得更糟。
所以;还有一个问题是:JIT 编译器是否足够聪明以忽略这些浪费的指令?
最佳答案
没关系。看来这无论如何也做不到。尝试加载此类类型将导致 TypeLoadException
类似
Could not load type 'MyValue' from assembly 'MyAssembly' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
所以,我猜想引用类型字段不可能与值类型字段位于相同的偏移量上。
故事结束。
我将离开这个问答(而不是删除),以防其他人好奇。
关于c# - 使用 "union struct"来避免 cast/box/unbox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35952571/
我很确定我不会是第一个被这个绊倒的人,但我找不到答案。这是作业。 class Tier{} class Fisch extends Tier{} class Vogel extends Tier{}
在接收器开发人员指南中如下: Applications running on the Google Cast receiver device (receiver applications) are a
最近我制作了一个自定义本地 Flask 网站,用于从本地设备转换到连接到我的电视的 RPi4。有一个 GUI它也可以通过 GET 请求控制,这是转换工作的主要方式,实际上是通过 GET 请求将数据从
最近我因为某些原因重置了我的路由器,所以当我尝试将它连接到 chromecast 时,Chromecast 没有在其列表中列出我的 wifi 名称。 之前它工作正常,所以我选择其他并手动输入我的网络名
做这样的 Actor 阵容的好方法是什么? seq { yield (box "key", box "val") } |> Seq.cast 因为这看起来非常难看: seq { yield (box
我继承的遗留 Web 应用程序是在经典 ASP 中为新西兰乐施会定制编写的,它在用户提交的输入上运行字符串替换,删除字符串“cast”,大概是因为 cast 函数。 然而,这意味着我们的参与者都不能拥
我去了三星网站并下载了 Media Control SDK 包。当我在我的 Galaxy S3 Android 4.3 上使用 AllShare Cast 视频播放器时,我的智能电视(在同一网络中)出
如何在 BigQuery 中查看 INT64 的二进制表示形式?将其转换为 BYTES 类型也可以。 最佳答案 正如@Elliot Brossard 所述,INT64 如何执行是一个实现问题。类型表示
Google 的文档要求我们设置自己的网络服务器来托管 receiver.html。 是否有任何人都可以使用的默认公共(public) chrome-cast 接收器? 我只需要非常基本的接收器,与
我在 Eclipse 3.6 (Helios) 中运行某人的代码时遇到问题。代码是用 OpenJDK 7 编写的。我运行的是 Windows 7,我必须为它安装 Java 7。我之前使用的是 Java
所以我有一些 COM 类型,它们的名称很难记住、又长又笨重,所以如果可以避免的话,我宁愿在从对象进行转换时不必键入它们。使用 Seq.cast 它将推断所需的类型并根据需要进行强制转换。 这是一个用
假设您不关心编译器和机器的转换风格,以下之间是否存在明显差异: #include #include #include static int64_t tosigned (void *p) {
我的测试类 XString 有两个转换运算符。但是编译器不会为 fooA 使用显式转换 operator const wchar_t*()。为什么? class XString { public:
我有以下代码: T imageCollectionItem; // This checks if image actually exists, if it doesn't it gets the ne
这有点假设,因为我不太担心性能 - 只是想知道一般来说哪个选项实际上最快/最有效,或者是否没有任何区别。 假设我有以下支持重载的访问者模板代码: #define IMPLEMENT_VISITOR_W
我目前正在存储复选框的真/假状态。在注册表中检查值以在下次加载表单时重置。 加载表单时,我获取值并像这样设置复选框。 string value = (string)Registry.GetValue(
enum Gender { Male, Female } var k = new[] { Gender.Male }.Cast().ToList().Cast().ToList(); //alrigh
我正在按照 https://codelabs.developers.google.com/codelabs/cast-receiver#0 上的教程构建一个 chrome cast 自定义接收器。我无
我看不懂以下作品 SELECT price, CAST(price AS DECIMAL(10,2)) FROM orders; 但是更新失败: UPDATE orders SET price = C
在 Cast v3 中,如何手动更改“停止转换”按钮的颜色? 我可以为其他所有内容更改转换对话框或媒体路由器的样式,但“停止转换”按钮似乎会根据背景颜色切换为黑色/蓝色。 我的主题:
我是一名优秀的程序员,十分优秀!