[译]分辨差别 -- 第三部分: fixed 和 fixed

本文探讨了C#中'fixed'关键字的双重含义:一是用于声明固定大小的缓冲区,二是防止对象在非安全代码中被垃圾回收器移动。并讨论了这种用法可能引起的混淆。

译自Eric Lippert's Blog, 原文: http://blogs.msdn.com/ericlippert/archive/2009/08/27/what-s-the-difference-between-fixed-and-fixed.aspx

    某天我收到一封这样开头的邮件:

    我有一个关于C# 固定大小的缓冲区的问题:

    unsafe struct FixedBuffer { public fixed int buffer[100]; }

    现在把缓冲区声明为固定的,它就是不可移动的...

    看到这个问题我的心都碎了。如果语言细节设计容易造成误解,那么上面所遇到的情况只是极为不幸的时刻之一。

    当在非安全的代码中对托管对象使用指针算法时,你要确保垃圾回收器不会把你正需要的内存移掉。当你正在用指针操作某个对象的时候,如果另外一个线程进行了资源回收,那么这个指针将完全混乱。因此,C#把变量分为“固定的”和“可变的”。如果你想要将指针应用到一个可移动的对象上,你可以使用“fixed”关键字来声明“这个局部变量是不能被垃圾回收器移动的”。当回收行为发生时,垃圾回收器要为那些正在进行的调用查看所有局部变量(那些被用到的变量需要保留);如果回收器看到某变量被标为“fixed”,它不会移动这样的变量,即使这会造成托管堆碎片(由此也看出让这样的变量固定的时间尽可能少是很重要的)。所以典型地,我们用“fixed”代表固定在某个地方。

    但是在这封邮件中的“fixed”并不是这个意思,这里的意思是将此问题中的buffer的大小固定为容纳100个int变量,本质上讲,这和在结构中创建100个int类型的成员是一样的。

    明显地,我们经常使用相同的关键字来表示概念上相同的东西。比如,在C#中我们经常用不同的方式使用关键字“internal”,但是所有的“internal”表示的意义都是一样的。它只是用来表示“一些实体的访问权限在同一程序集的代码中是不受限制的”。

    某些时候我们也用相同的关键字来表示概念上完全不同的东西,这要依赖于用户使用的上下文环境来确定它代表的意思。比如:

var results = from c in customers where c.City == "London" select c;

class C where T : IComparable

    很明显“where”使用于两种完全不同的方式:建立查询语句中的筛选从句,和声明一个泛型参数的约束类型。

    如果一个关键字用于两种不同的意义但是这个区别非常细微,就像我们上面举到的例子,这会使人们碰到困难。那个用户的邮件将会继续问上一大堆的问题,但是这些问题都是基于一个不正确的假设——一个固定大小的缓冲区会自动地固定在内存中的某一位置。

    这只能说这是一个不好的术语的混用:“固定大小”和“固定位置”都是使用“fixed”,但是使用的方式不同,这是很让人头疼的事情。然而它们之间的关联比这还要复杂:只有当某固定大小的缓冲区的容器被固定在某块内存区,你才能安全地访问存储在该缓冲区中的数据。在这个问题中,这两个概念具有很强的相关性,但是并不完全相同。

    一方面,为了减少混乱,我们可以使用两个不同的关键字,比如说“pinned”和“fixed”。但是另一方面,“fixed”的所有用法只在非安全代码中才可用。对于非安全的码的所有特性,一个关键的前提假设就是:如果你想在C#中使用非安全代码,那么你肯定已经是一个完全理解CLR中内存管理的编程专家。这也是为什么我们让你在代码中标明“unsafe”的原因;它表明你关闭了安全系统并且知道自己在做什么。

    在C#中可以多用的一些重要的关键字:fixed, into, partial, out, in, new, delegate, where, using, class, struct, true, false, base, this, event, return和void都至少包含两种以上不同的意思。大部分的在位于特定上下文中的时候都很清楚,但是至少前三个——fixed, into和partial——已经造成了很多的困扰,我已经收到了很多困惑的用户关于它们使用区别的问题。我接下来会看一下“into”和“partial”。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12639172/viewspace-616445/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12639172/viewspace-616445/

<template> <view class="page-container"> <!-- 打开弹框的按钮 --> <!-- 遮罩层 --> <view class="mask" v-if="localShow" @click="hideDialog"></view> <!-- 弹框 --> <view class="dialog" :class="{ 'dialog-show': localShow }"> <view class="dialog-content"> <view class="dialog-header"> <text class="dialog-title">提示</text> <text class="close-icon" @click="hideDialog">×</text> </view> <view > <button >确定</button> <button >取消</button> </view> </view> </view> </view> </template> <script> export default { props: { showDialog: { type: Boolean, default: false, }, showModel: { type: Boolean, default: false, }, }, watch: { showModel(newVal) { // 监听父组件数据变化 this.localShow = newVal; }, }, data() { return { localShow: this.showDialog, // 本地副本 // 返回假数据 data: { }, }; }, created() { console.log("onload", this.showDialog); this.getLicenseList(); }, onload() { console.log("onload", this.showDialog); }, methods: { // 隐藏弹框 hideDialog() { this.localShow = false; this.$emit("update:show-model", false); // 通知父组件更新 }, }, }; </script> <style lang="scss" scoped> .page-container { padding: 20rpx; font-family: "PingFangSC-Regular", "PingFang SC", sans-serif; font-weight: 400; font-style: normal; color: #0d0d0d; background: #f3f5f8; } .mask { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 998; } .dialog { position: fixed; bottom: -100%; left: 0; width: 100%; height: calc(100% * 2 / 3); transition: bottom 0.3s ease; z-index: 999; display: flex; justify-content: center; align-items: flex-end; // bottom: 0; } .dialog-show { bottom: 0; } .dialog-content { background-color: #fff; width: 100%; height: 100%; border-top-left-radius: 10rpx; border-top-right-radius: 10rpx; padding: 30rpx; box-sizing: border-box; } .dialog-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 20rpx; border-bottom: 1rpx solid #ccc; } .dialog-title { font-size: 32rpx; font-weight: normal; text-align: center; flex: 1; } .close-icon { font-size: 36rpx; cursor: pointer; } .radio-group { margin-top: 60rpx; } .radio-item { display: flex; align-items: center; margin-bottom: 10rpx; font-size: 28rpx; } .radio-item radio { transform: scale(0.6); } .audit-status { display: flex; justify-content: space-between; align-items: center; margin-top: 25rpx; padding: 15rpx; padding-top: 30rpx; background-color: rgba(245, 246, 249, 1); border-radius: 15rpx; } .status-label { font-size: 28rpx; } .status-value { display: flex; font-size: 28rpx; } .audit-text { color: #d01212; } .audit-date { color: #666; margin-top: 10rpx; font-family: "PingFangSC-Regular", "PingFang SC", sans-serif; font-weight: 400; font-style: normal; color: #0d0d0d; } .dialog-footer { padding-top: 20rpx; text-align: center; margin-top: 25rpx !important; } /deep/.next-button { width: 80%; padding: 10rpx; background-color: rgba(12, 195, 199, 1) !important; border: none !important; color: #fff !important; border-radius: 15rpx; font-size: 30rpx; } .titleName { margin-top: 40rpx; } .radioName { margin-top: 40rpx; } </style>去除无用的方法样式,并将按钮放在一排 中间部分加上一个操作流程例子展示
07-14
filterEdit = new QLineEdit(); filterEdit->setObjectName("filterEdit"); filterEdit->setClearButtonEnabled(true); filterEdit->setPlaceholderText("filter"); filterEdit->setContentsMargins(3,3,3,3); filterEdit->setAlignment(Qt::AlignLeft) ; connect(filterEdit, &QLineEdit::returnPressed, this ,[&](){ //TODO:过滤功能的代码 }); //TODO:补全菜单仅仅是示例,后续外部引用filterEdit添加即可 `filterEdit` 不会管理 `completer` \ filterAction 的内存。 //【示例】为搜索框设置补全菜单 QStringList strList = {"ipv4", "udp port","tcp port", "src", "dst"}; QCompleter* completer = new QCompleter(strList, filterEdit); completer->setCaseSensitivity(Qt::CaseInsensitive);//不区分大小写 completer->setMaxVisibleItems(10); //自动补全列表最多显示10个选项 completer->setFilterMode(Qt::MatchContains); //支持模糊匹配 completer->setModelSorting(QCompleter::CaseSensitivelySortedModel); completer->setCompletionColumn(0); //基于第一列的内容来提供匹配建议,list的时候不需要 filterEdit->setCompleter(completer); //为过滤框左侧添加过滤图标 QAction* filterAction = new QAction(filterEdit); filterAction->setToolTip("filter"); filterAction->setIcon(QIcon(":/icon/filter.png")); filterAction->setCheckable(true); filterEdit->addAction(filterAction, QLineEdit::LeadingPosition); // filterEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); QWidget *space = new QWidget(this); space->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); toolBar->addWidget(fileButton); toolBar->addAction(startAct); toolBar->addAction(decodeAct); toolBar->addAction(foldAct); toolBar->addWidget(space);//使过滤框显示在工具栏最右侧 toolBar->addWidget(filterEdit); toolBar->setIconSize(QSize(16,16)); toolBar->setStyleSheet("font-family: Microsoft YaHei");怎么调整filterEdit的大小
03-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值