我继承了一些广泛而不必要地使用ref关键字的代码.如果不使用ref,原始开发人员显然担心对象会被克隆为原始类型,并且在编写50k +代码行之前没有费心去研究这个问题.
这与其他不良编码实践相结合,创造了一些表面上非常危险的情况.例如:
Customer person = NextInLine();
//person is Alice
person.DataBackend.ChangeAddress(ref person, newAddress);
//person could now be Bob, Eve, or null
Run Code Online (Sandbox Code Playgroud)
你能想象走进商店改变你的地址,走出一个完全不同的人吗?
可怕,但在实践中,在这个应用程序中使用ref似乎是无害的多余.我无法证明清理它需要花费大量时间.为了帮助推销这个想法,我提出了以下问题:
我特别关心维护.具有实例的合理答案是优选的.
我们也欢迎你争辩说没有必要进行清理.
有没有办法在下面的代码中保持相同的功能,但无需创建委托?我正在与包含许多各种DeleteSomethingX(ref IntPtr ptr)方法的第三方API接口,我正在尝试集中IntPtr.Zero检查的代码.
private void delegate CleanupDelegate(ref IntPtr ptr);
...
private void Cleanup(ref IntPtr ptr, CleanupDelegate cleanup)
{
if (ptr != IntPtr.Zero)
{
cleanup(ref ptr);
}
}
Run Code Online (Sandbox Code Playgroud) 我正在努力如何在真正的应用程序中使用"ref"(通过引用传递参数).我想有一个简单而有意义的例子.到目前为止我发现的所有内容都可以通过向方法添加返回类型来轻松重做.有人在想吗?谢谢!
我想假设这个问题的目的是检查是否至少有一种方法,即使通过最不安全的黑客,仍然保持对非blittable值类型的引用.我知道这种设计类型与犯罪相当; 除了学习之外,我不会在任何实际案例中使用它.因此,请接受现在阅读异常不安全的代码.
我们知道可以以这种方式存储和增加对blittable类型的引用:
unsafe class Foo
{
void* _ptr;
public void Fix(ref int value)
{
fixed (void* ptr = &value) _ptr = ptr;
}
public void Increment()
{
var pointer = (int*) _ptr;
(*pointer)++;
}
}
Run Code Online (Sandbox Code Playgroud)
在安全性方面,上述类别可以与虚空中的跳跃相媲美(没有双关语意),但正如这里已经提到的那样.如果在堆栈上分配的变量传递给它,然后调用方法的作用域终止,则可能会遇到错误或显式访问冲突错误.但是,如果您执行这样的程序:
static class Program
{
static int _fieldValue = 42;
public static void Main(string[] args)
{
var foo = new Foo();
foo.Fix(ref _fieldValue);
foo.Increment();
}
}
Run Code Online (Sandbox Code Playgroud)
在卸载相关应用程序域之前,不会处理该类,因此适用于该字段.老实说,我不知道高频堆中的字段是否可以重新分配,但我个人认为不是.但是现在让我们放弃安全(如果可能的话).在阅读了这个和这些问题后,我想知道是否有办法为非blittable静态类型创建类似的方法,所以我制作了这个程序,它实际上有效.阅读评论以了解它的作用.
static class Program
{
static Action _event;
public static …Run Code Online (Sandbox Code Playgroud) 如何为一个mongoose模式的一个属性编写多个ref,就像这样(但是错误的):
var Schema = mongoose.Schema;
var PeopleSchema = new Schema({
peopleType:{
type: Schema.Types.ObjectId,
ref: ['A', 'B'] /*or 'A, B'*/
}
})
Run Code Online (Sandbox Code Playgroud) 作为一个对.NET管道不太了解的程序员,我想知道使用ref字符串作为参数是否有利于C#的性能?
假设我有一个像这样的方法:
public int FindSomething(string text)
{
//Finds a char in the text and returns its index
}
Run Code Online (Sandbox Code Playgroud)
当我使用这个方法时,编译器会为方法创建一个文本副本,对吧?
但是,如果我使用ref关键字:
public int FindSomething(ref string text)
{
//Finds a char in the text and returns its index
}
Run Code Online (Sandbox Code Playgroud)
..编译器应该只发送文本的指针地址...
那么使用ref这样的性能有好处吗?
我已经研究了一下,似乎常识认为结构应该在16字节以下,否则它们会导致复制的性能损失.使用C#7和ref返回,完全避免完全避免复制结构变得非常容易.我假设随着结构大小变小,通过ref传递更多的开销只是复制值.
是否有一个经验法则,关于何时通过值传递结构比通过ref更快?哪些因素会影响这个?(结构大小,过程位数等)
更多上下文:我正在开发一款游戏,绝大多数数据都表示为连续的结构数组,以实现最大的缓存友好性.正如您可能想象的那样,在这种情况下传递结构很常见.我知道分析是确定某些内容的性能影响的唯一真正方法.但是,我想了解它背后的理论概念,并希望在编写代码时考虑到这种理解,并仅描述边缘情况.
此外,请注意,我不会询问最佳做法或通过参考传递一切的理智.我知道"最佳实践"和含义,我故意选择不遵循它们.
按值传递vs传递参考性能C#.net - 此问题讨论通过ref传递引用类型,这与我要求的完全不同.
在.Net中,出于性能原因,我是否应该通过引用传递结构? - 第二个问题涉及到主题,但它是关于结构的特定大小.
要回答Eric Lippert的文章中提出的问题:
你真的需要回答这个问题吗?是的,我愿意.因为它会影响我编写大量代码的方式.
这真的是瓶颈吗?可能不是.但我仍然想知道,因为99%的程序是数据访问模式.在我看来,这类似于选择正确的数据结构.
差异是否相关?它是.通过ref传递大型结构更快.我只是想了解这个的局限性.
你说的这个"更快"是什么?与为同一任务减少CPU工作量相同.
你在看大局吗?是.如前所述,它影响我如何写整个事情.
你为什么甚至问我?因为SO应该是一个Q&A网站.
我知道我可以测量很多不同的组合.这告诉我什么?在我的[.NET版本,进程位,操作系统,CPU]的组合中,X比Y更快.Linux怎么样?Android怎么样?iOS怎么样?我应该对所有可能的硬件/软件组合的所有排列进行基准测试吗?
我认为这不是一个可行的策略.因此,我在这里问一下,对CLR/JIT/ASM/CPU有很多了解的人可以告诉我它是如何工作的,这样我就可以在编写代码时做出明智的决定.
我正在寻找的答案类似于前面提到的结构大小的16字节指南,并解释了原因.
我正在尝试在React Native中添加一个函数组件的ref,以便在FlatList组件上使用scrollToEnd.
我想使用重构为此,并且正如他们的文档所述,toClass()应该能够处理这个问题.但是,没有给出任何例子.
目前,这是我失败的实施.有人能告诉我我做错了什么吗?
我非常感激!
import React from 'react';
import PropTypes from 'prop-types';
import { FlatList, View, Text } from 'react-native';
import { graphql } from 'react-apollo';
import { compose, toClass, lifecycle } from 'recompose';
import CommentItem from './CommentItem';
import { commentsQuery } from '../../queries/comments';
const CommentScreen = ({ onRef, currentUser, data: { comments, loading } }) => {
if (loading) {
return (
<View>
<Text>Loading...</Text>
</View>
);
}
return (
<FlatList
ref={ref => {
this.refs.commentList = ref;
}}
data={comments} …Run Code Online (Sandbox Code Playgroud) 我原来的代码是这样的:
handleClick() {
var name = this.refs.name.value;
var description = this.refs.description.value
}
render () {
return (
<React.Fragment>
<input ref='name' placeholder='Enter the name of the item' />
<input ref='description' placeholder='Enter a description' />
<Button onClick={this.handleClick.bind(this)}>Submit</Button>
</React.Fragment>
);}
Run Code Online (Sandbox Code Playgroud)
name并且description可以正确获取输入。但是当我使用<TextField>:
<TextField ref='name' placeholder='Enter the name of the item' />
Run Code Online (Sandbox Code Playgroud)
它显示传递的值是null,似乎ref不起作用。谁能帮我解决这个问题?
我知道 refs 用于直接访问 DOM 元素而不改变状态。我读到无法为功能组件提供引用,因为它们没有状态。
Refs 不能附加到函数组件。虽然,我们可以定义 refs 并将它们附加到 DOM 元素或类组件。底线是——函数组件没有实例,所以你不能引用它们。
取自:https : //blog.logrocket.com/cleaning-up-the-dom-with-forwardref-in-react/
我还是不明白。
我正在使用TooltipAnt Design ( https://ant.design/components/tooltip/ ) 中的Button组件、组件和自定义CircleButton组件。
鉴于以下 JSX:
<Tooltip placement="left" title={"Lock slot"}>
<CircleButton onClick={() => execute(client.close)} icon={<LockOutlined />} disabled={loading} />
</Tooltip>
Run Code Online (Sandbox Code Playgroud)
还有我的 CircleButton 组件。像这样使用,它会产生警告。
const CircleButton = (props) => // gives the warning
<Button shape="circle" size="small" style={{ marginRight: "8px" }} {...props} />
Run Code Online (Sandbox Code Playgroud)
警告:不能为函数组件提供引用。尝试访问此引用将失败。你的意思是使用 React.forwardRef() 吗?
请注意,尽管有警告,但一切都按预期工作。
如果我按如下方式编辑它,它会正常工作,为什么?
const CircleButton = forwardRef((props, ref) => // doesn't give …Run Code Online (Sandbox Code Playgroud) ref ×10
c# ×6
delegates ×2
performance ×2
reactjs ×2
.net ×1
javascript ×1
material-ui ×1
mongodb ×1
mongoose ×1
pointers ×1
react-native ×1
recompose ×1
schema ×1
string ×1
struct ×1
textfield ×1
unsafe ×1