请考虑以下事项:
class A {}
class B : A {}
class C
{
C()
{
var b = new B();
Foo(b);
Foo2(ref b); // <= compile-time error:
// "The 'ref' argument doesn't match the parameter type"
}
void Foo(A a) {}
void Foo2(ref A a) {}
}
Run Code Online (Sandbox Code Playgroud)
为什么会发生上述编译时错误?两者ref和out参数都会发生这种情况.
据我所知,out参数的唯一用途是调用者可以从单个方法调用中获取多个返回值.但我们也可以使用ref参数获取多个结果值!
那么有没有其他情况下out参数可以证明是有用的,而我们不能使用ref参数呢?
谢谢.
当我对一个out或ref参数进行赋值时,是否会立即将值赋给调用者提供的引用,还是在方法返回时分配给引用的out和ref参数值?如果方法抛出异常,则返回值吗?
例如:
int callerOutValue = 1;
int callerRefValue = 1;
MyMethod(123456, out callerOutValue, ref callerRefValue);
bool MyMethod(int inValue, out int outValue, ref int refValue)
{
outValue = 2;
refValue = 2;
throw new ArgumentException();
// Is callerOutValue 1 or 2?
// Is callerRefValue 1 or 2?
}
Run Code Online (Sandbox Code Playgroud) 我最近碰到了一个讨厌的bug,简化的代码如下所示:
int x = 0;
x += Increment(ref x);
Run Code Online (Sandbox Code Playgroud)
...
private int Increment(ref int parameter) {
parameter += 1;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
增量调用后的x值为1!一旦我发现发生了什么,这是一个简单的解决方案.我将返回值分配给临时变量,然后更新x.我想知道是什么解释了这个问题.这是我在忽略的规范或C#的某些方面.
我有一个类,主要是大阵列的包装和一些相关的内务处理.我有一个带参数的函数.当我将类的实例传递给函数时,我希望数组被发送.
我考虑过明确的演员表.假设我有一些具有byte [] ref参数的函数.
public void SomeFunction(ref byte[] someBytes);
Run Code Online (Sandbox Code Playgroud)
而且我有一些带有重载显式转换的类.
class SomeClass
{
byte[] someBytes;
public static explicit operator byte[](SomeClass someInstance)
{
return someInstance.someBytes;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想以类作为参数调用该函数
SomeClass someInstance = new SomeClass();
SomeFunction(ref (byte[]) someInstance);
Run Code Online (Sandbox Code Playgroud)
编译器抱怨"ref或out参数必须是可赋值变量".我不确定我是不是没有正确地按摩编译器,或者你真的不能这样做.
我考虑了属性或函数返回值,但你不能通过ref传递那些(并且在自我教育之后我明白为什么......)
我不想让数组成为公共字段,但这确实满足了编译器.我想我可以创建一个局部变量来引用数组,但这是在每个函数调用之前和之后的额外代码行...
编辑:可能值得注意的是SomeFunction是由第三方编写的,我无权更改它.更糟糕的是,我不认为他们的参数实际上需要参考...
我有一个C#extern声明,如下所示:
[DllImport("something.dll")]
public static extern ReturnCode GetParent(IntPtr inRef, out IntPtr outParentRef);
Run Code Online (Sandbox Code Playgroud)
如何将其翻译为F#?
C#7引入内联out参数的具体原因是ref什么?
以下内容适用于C#7:
int.TryParse("123", out _);
Run Code Online (Sandbox Code Playgroud)
但这是无效的:
public void Foo(ref int x) { }
Foo(ref _); // error
Run Code Online (Sandbox Code Playgroud)
我没有看到为什么不能将相同的逻辑应用于ref参数的原因.
我正在阅读有关WCF和IDispatchMessageInspector的一些C#文档,并且该接口定义了一个通过引用传递的"Message"对象,以便可以对其进行操作.
当您通过ref传递某些东西而不是正常传递时,堆栈上实际发生了什么?
我需要在一个方法中将long转发为int,其中long作为ref变量传递:
public void Foo(ref long l)
{
// need to consume l as an int
}
Run Code Online (Sandbox Code Playgroud)
我怎么能轻松做到这一点?
ref-parameters ×10
c# ×9
.net ×3
casting ×2
c#-7.0 ×1
extern ×1
f# ×1
pinvoke ×1
polymorphism ×1
stack ×1