如何忽略/丢弃C#中的"out"变量?

5

假设我已经拿到了一个类似于下面这样的函数:

int doSomething(int parameter, out someBigMemoryClass uselessOutput) {...}

我想使用这个函数,但我完全不需要uselessOutput变量。如何在不使用uselessOutput的情况下让函数工作,最好不要分配任何新的内存?


4
如果您不能修改这个方法,那么因为这个方法进行了初始化,所以您无法做任何事情。如果您不使用它,垃圾收集器会在需要时回收这些内存。 - Tim Schmelter
2个回答

9

简单来说,你不能这样做。要么传递一个变量并忽略之后的out(如果从分配out参数产生的内存开销很小,即不需要大量内存),要么自己编辑该函数的代码。

我现在想到的一种方法是将该函数进行包装,这样如果每次都必须传递一个被忽略的out变量会很麻烦。它不能消除原始函数中的out,但它提供了一种在调用该函数时完全不关心out变量的方法。

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void MethodWrapper() 
    {
        int i = 0;
        Method(out i);
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44

        MethodWrapper();
        // No value needed to be passed - function is wrapped. Method is still called within MethodWrapper, however.
    }
}

然而,这并不能解决你的大内存类问题,如果你经常调用它的话。为了解决这个问题,你需要重写这个函数。不幸的是,在包装函数中调用它仍然需要相同的内存分配。


如果该方法对未使用的参数进行了一些密集操作以赋值,那么内存开销将不会那么微不足道。 - Sehnsucht
@Sehnsucht 我会假设这不是问题,因为通常情况下并非如此。虽然问题没有指定这是一个问题,但如果是的话,需要更好的解决方案。stakx在下面提供了一个解决方案,可能有助于避免这个问题。这样可以相当巧妙地避免了out参数。 - Nick Bull
@Sehnsucht 另外,如果在参数上执行了密集操作,那么这种性能损失不是总会存在吗?无论方法如何包装,您都需要删除执行密集函数的代码。这将始终需要重写该函数,除非我忽略了什么。 - Nick Bull
1
使用 out 参数的问题在于,如果需要,我们可以将其赋值为 null(适当类型化);而分配值的角色是由方法扮演的;因此,如果按照 OP 所指出的某个大型内存类别,很有可能会在被调用的方法内部进行分配,而不管我们给它什么值。 - Sehnsucht
好的!我会思考一下...编辑:思考已经完成,我想不出其他方法而不需要编辑方法本身。我会更新我的答案,以反映大内存类的情况。 - Nick Bull
感谢您宝贵的想法,我实际上已经使用了另一种方法来实现我的更大目标,但这个较小问题的解决方案可能会在不久的将来派上用场,我真的很喜欢stakx的答案。似乎 out 不会复制任何内容并且会直接写入您提供的变量,因此如果没有访问原始函数的权限,内存问题就无法真正得到解决。 - Scar

2

没有简单地省略out参数的方法,但您可以通过将方法包装在不带out参数的扩展方法中,使您的生活更加舒适:

// let's assume the method in question is defined on type `Foo`:
static class FooExtensions
{
    public static int doSomething(this Foo foo, int parameter)
    {
        someBigMemoryClass _;
        return foo.doSomething(parameter, out _);
    }
}

然后调用该扩展方法,而不是实际的实例方法:

Foo foo = …;
int result = foo.doSomething(42);

(当你确实需要指定 out 参数时,你仍然可以这样做,因为原始方法仍然存在。)

当然,原始方法仍将产生不必要的 someBigMemoryClass 对象,这可能会浪费资源(希望是短暂的)。如果有可能,最好直接更改原始方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接