C#中有趣的类型系统违规(在安全的环境中)

Shl*_*itz 2 .net c#

我谈到的类型系统违规 - 是在模仿工会时.

为什么在安全的环境中允许它?

  • 它允许您处理值类型,作为不同的值类型 - 就像您将实现的那样:

    float f = 2.5f;
    int binaryIdenticalInt =*((int*)&f);

  • 它允许您引用类型为X的对象,因为它是Y类型,即使这些类型之间没有关系.

  • 它允许您创建CLR甚至不会加载的类型(如果至少有一个重叠字段是引用类型,并且其中至少有一个是值/指针类型 - CLR将拒绝加载它).我希望C#编译器比它允许的内容更加挑剔,而不是CLR.不低于.

那么,为什么编译器首先在安全的上下文中允许这样的东西呢?为什么它不需要具有显式布局的类型的不安全上下文,它们具有重叠的字段?

我希望那里有人有答案 - 因为它必须有趣.

示例(所有编译都没有不安全的块,甚至不安全的开关):

[StructLayout(LayoutKind.Explicit)]
struct ValueUnion
{
    [FieldOffset(0)]
    public int i;

    [FieldOffset(0)]
    public float f;
}

[StructLayout(LayoutKind.Explicit)]
struct ReferenceUnion
{
    [FieldOffset(0)]
    public string str;

    [FieldOffset(0)]
    public Stream stream;
}

[StructLayout(LayoutKind.Explicit)]
struct CLRWontLoad
{
    [FieldOffset(0)]
    public string str;

    [FieldOffset(0)]
    public IntPtr ptr;
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 7

让我回答一些略有不同的问题.

使用显式布局属性是否允许违反类型安全而不使用unsafe关键字?

是.这就是它的用途.

FieldOffset编译器具有哪些属性知识?

编译器验证该FieldOffset属性不在static/const字段上,并且它与该StructLayout属性一致.它不会检查有关属性有效性的任何其他内容.

为什么C#编译器没有检测到属性的潜在不安全使用并需要unsafe关键字?

这是一个功能.为了供您使用,必须考虑,设计,指定,实施,测试,记录功能并将其发送给客户.这个功能被认为是.它没有设计,指定,实施,测试,记录或发货,因此没有这样的功能.

这是一个令人不满意的答案.

我的建议是不要在StackOverflow上询问"为什么"这些问题."为什么"问题含糊不清,因此你经常得到不满意的答案."为什么不"这些问题更难以令人满意地回答,因为他们有这样的假设,即世界不应该成为一种不是这样的方式的充分理由.

好的,让我改一下.如果这个功能是针对编译器设计团队的,那么在决定是否继续使用该功能时,他们可能会考虑哪些优缺点?

  • Pro:代码可以明确地以不安全的方式使用,因此应该要求unsafe关键字允许它.

  • Con:unsafe关键字是为了防止意外使用危险的不安全功能,这四十年的C已经向我们展示了即使是专业程序员也难以发现错误的功能.无法意外使用struct layout属性.可以假设使用此属性的人确切地知道他们正在做什么,并且有充分的理由知道他们正在做什么.

在我看来,这里的优点超过了职业选手.对于适中的成本,该功能将是非常小的益处.

请记住,实现的每个功能都意味着列表中的另一个功能实现,因为预算是有限的.我不想做这个弱功能,必须削减一个实际上让开发人员受益的功能.

团队是否考虑过此功能并在此基础上拒绝了此功能?

是.看到

http://connect.microsoft.com/VisualStudio/feedback/details/357828/using-explicit-struct-layout-causes-compiler-to-produce-unverifiable-code