微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 为什么使用“部分”时类级“不安全”修饰符不一致?

我已经注意到在类级别对部分类使用unsafe修饰符时的某种行为,我希望得到一些澄清.

我一直在研究一个相当大的包装器,为了理智,我使用partial修饰器分割多个文件.包装器大量使用不安全的指针,因此我选择在类级别上简单地声明它以覆盖其中的所有内容.

public static unsafe partial class Ruby
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static VALUE CLASS_OF(VALUE obj) => ((RBasic*) obj)->klass;
}

在另一个文件中:

public static unsafe partial class Ruby
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void* DATA_PTR(VALUE obj) => ((RData*) obj)->data;
}

每个部分声明都需要unsafe修饰符,以便“允许”和编译不安全的代码,这是可以理解的,我希望部分类的类声明需要完全匹配.

但是使用这个逻辑,我也被允许有另一个不安全的文件

[SuppressUnmanagedCodeSecurity]
public static partial class Ruby
{
    [DllImport(RUBY_LIBRARY,CallingConvention = CallingConvention.Cdecl)]
    public static extern VALUE rb_ivar_get(VALUE obj,ID name);
}

在这里,我不使用unsafe修饰符,它是完全可以接受的(显然这个文件中没有不安全的代码).

我是什么希望得到澄清为什么这允许.每个分类的类声明不应该完全匹配吗?不允许更改/排除任何其他类修饰符,例如私有,公共,抽象等,所以为什么这是不安全的.在我看来,这种行为似乎不一致.我的猜测是,它在不同的情况下由编译器在不同的上下文中运行,但这只是我的猜想,并且希望有人比我更了解这个可能会有所启发.

解决方法

关于需要一致性的修饰语的断言有点过时了.例如,这是完全有效的:
public abstract partial class Foo { }

partial class Foo { }

Foo将表示一个抽象类,因为它的一个部分被声明为abstract.有关部分类的类修饰符的规则可以在规范的10.2.2节中找到.这是与不安全的部分类相关的文本:

When the unsafe modifier is used on a partial type declaration,only that particular part is considered an unsafe context (§18.1).

当密封或抽象应用于部分类时,该类的所有部分都被认为是密封的或抽象的.但它不能同时存在.

实际上,可访问性是partials上唯一必须在所有部分之间保持一致的类修饰符,但不需要在所有部分中设置.

When a partial type declaration includes an accessibility specification (the public,protected,internal,and private modifiers) it must agree with all other parts that include an accessibility specification. If no part of a partial type includes an accessibility specification,the type is given the appropriate default accessibility (§3.5.1).

这基本上归结为不允许声明公共部分类Bar和内部部分类Bar,因为部件之间的可访问性变得不一致.声明没有可访问性的其他部分将认为已声明的可访问性,或认值为规范3.5.1节中规定的规则.

注意:我引用的规范部分来自Visual Studio 2017附带的规范版本.

ECMA-334参考文献如下:

23.2:

When the unsafe modifier is used on a partial type declaration (§15.2.7),only that particular part is
considered an unsafe context.

15.2.2.1:

When a partial type declaration (§15.2.7) includes an accessibility specification (via the public,
protected,and private modifiers),that specification shall agree with all other parts that
include an accessibility specification. If no part of a partial type includes an accessibility specification,the
type is given the appropriate default accessibility (§8.5.2).

15.2.2.2和15.2.2.3有关于抽象和密封修饰符的规则.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


原文地址:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx 原文发布日期: 9/19/2005 原文已经被 Microsoft 删除了,收集过程中发现很多文章图都不全,那是因为原文的图都不全,所以特收集完整全文。 目录 前言 CLR启动程序
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采纳和使用,它的确提供了很多的优势也解决了很多的问题,但是我们也知道也并不是银弹,提供优势的同时它也给我们的开发人员和团队也带来了很多的挑战。 为了迎接或者采用这些新技术,开发团队需要更加注重一些流程或工具的使用,这样才能更好的适应这些新技术所
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下PLINQ中的分区。上一篇介绍了并行编程,这边详细介绍一下并行编程中的分区和自定义分区。 先做个假设,假设我们有一个200Mb的文本文件需要读取,怎么样才能做到最优的速度呢?对,很显然就是拆分,把文本文件拆分成很多个小文件,充分利用我们计算机中
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Microsoft为了利用这个硬件特性,于是在Visual Studio 2010 和 .NET Framework 4的发布及以上版本中,添加了并行编程这个新特性,我想它以后势必会改变我们的开发方式。 在以前或者说现在,我们在并行开发的时候可
c语言输入成绩怎么判断等级
字符型数据在内存中的存储形式是什么
c语言怎么求字符串的长度并输出
c语言函数的三种调用方式是什么
c语言中保留两位小数怎么表示
double的输入格式符是什么