在运行时测试传入的 ByRef 参数是不是与给定的“其他”变量共享存储位置

Posted

技术标签:

【中文标题】在运行时测试传入的 ByRef 参数是不是与给定的“其他”变量共享存储位置【英文标题】:Test at runtime if a passed in ByRef parameter shares storage location with a given "other" variable在运行时测试传入的 ByRef 参数是否与给定的“其他”变量共享存储位置 【发布时间】:2013-06-27 16:21:12 【问题描述】:

这个问题更多是出于好奇而不是出于实际需要。

有什么方法可以测试传入ByRef(即C# 中的refout)参数的参数是否与某个“其他”变量具有相同的存储位置?我并不是要测试对象是否相同,因为两个不同的引用变量可能是对同一对象的两个不同的引用。

我想出了一些例子来解释我的意思。考虑:

public static void SillySwap(ref int a, ref int b)

  // first put sum of original numbers into slot a,
  // then use that to get out the original numbers swapped
  a = a + b;
  b = a - b;
  a = a - b;

(我们通常会使用第三个临时变量,但为了说明我的问题,我会这样做。)SillySwap 如果您使用 两个 变量(相同或不同)就可以正常工作在数值上。但如果你这样称呼它:

int shared = 42;
SillySwap(ref shared, ref shared);

它将消灭shared如果ab 与存储位置相同,我有什么方法可以在SillySwap 的内部进行测试?

这是一个带有字段(“类变量”)的修改示例:

protected static int field;
public static void SillySwap2(ref int arg)

  arg = arg + field;
  field = arg - field;
  arg = arg - field;

这里我们要检查传入的arg是否真的是变量field

最后一个例子,考虑这个:

static bool SillyTryGetStrings(out string first, out string second)

  // the order of assignment may matter here!
  second = "world";
  first = "Hello";

  return true;

假设某个陌生人为firstsecond 传入了同一个变量。我们可以在方法中检查它吗?

【问题讨论】:

【参考方案1】:

一种方法是使用不安全的代码并比较指向变量的指针:

public unsafe bool AreRefsEqual(ref int a, ref int b)

    fixed (int* aptr = &a)
    fixed (int* bptr = &b)
    
        return aptr == bptr;
             


[TestMethod]
public void ShouldRefsEqualWork()

    int a = 1, b = 1;
    Assert.IsTrue(AreRefsEqual(ref a, ref a));
    Assert.IsFalse(AreRefsEqual(ref a, ref b));           

【讨论】:

非常有趣。您的 unsafe 方法是否可以通用以适用于所有值类型和引用类型,而不仅仅是 int 我不认为它可以在 c# 中完成,因为无论约束如何,您都无法获取泛型类型的地址(您只能获取少数类型的地址)。我认为这在 C++/CLI 中是可能的。 所以你的解决方案只是部分的。它有一些限制。 (1) 它仅适用于值类型(并且仅适用于没有引用类型的实例字段的值类型)。 (2)我认为,使用未分配变量的一元& 运算符获取地址是合法的,所以如果我有一个out int i 参数并且想在开始时检查它的地址,我可以使用你的代码“ inline”,但我认为它不允许我将 i 传递给您的 AreRefsEqual 方法,因为它不是绝对分配的。

以上是关于在运行时测试传入的 ByRef 参数是不是与给定的“其他”变量共享存储位置的主要内容,如果未能解决你的问题,请参考以下文章

ByRef 参数类型与布尔值不匹配

在 Android Studio 中运行参数化单元测试时,未找到给定的测试包括错误

optional [byval byref] [paramarray] 变量名() as 数据类型

从被调用的函数调用函数时 VBA byref 参数类型不匹配

Visual Basic 6.0中ByVal和ByRef的区别和应用示例!optional和缺省时的区别和应用示例!

VBA ByRef Argument Type Mismatch string into string