Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# &引用;使用;输出参数_C# - Fatal编程技术网

C# &引用;使用;输出参数

C# &引用;使用;输出参数,c#,C#,让我们假设我有一个简单的类,它是一次性的: class CanDispose : IDisposable { ... } 现在我可以很明显地把它放在一个“使用”块中,让它进行处理: using (var myDisposable = new CanDispose()) { ... } 但是,如果我有一个工厂方法,它通过out参数返回一次性数据,该怎么办?在我的示例中,可以有多个返回,因此多个输出是干净的: public bool CreateDisposable(out Can

让我们假设我有一个简单的类,它是一次性的:

class CanDispose : IDisposable
{
   ...
}
现在我可以很明显地把它放在一个“使用”块中,让它进行处理:

using (var myDisposable = new CanDispose())
{
    ...
}
但是,如果我有一个工厂方法,它通过out参数返回一次性数据,该怎么办?在我的示例中,可以有多个返回,因此多个输出是干净的:

public bool CreateDisposable(out CanDispose canDispose)
{
   canDispose = new CanDispose();
   ...
   return ret; 
}
如何将其放入using语句中?简单地将函数调用放入using块似乎不起作用。我必须求助于返回一个元组(这样行吗?),还是有更简单的方法

注意,这似乎不起作用。至少它没有关闭关于在超出范围之前处理的警告:

using (CreateDisposable(out CanDispose myDispose))
{
    ....
}

使用语句的
不必声明变量。将一次性变量作为
out
参数并不理想,您应该在自己的代码中避免使用它,但是如果您使用的是执行此操作的库,则可以在调用方法后使用
块的表达式将变量放入

CreateDisposable(out-CanDispose-myDispose);
使用(myDispose)
{
}
如何将其放入using语句中

你没有。这两种模式——out参数和使用
通过
自动处理——组合不好

我必须返回元组吗(这样行吗?)

我注意到“这行得通吗?”这种形式的问题可以通过尝试来回答。但为了避免这些击键:元组不是一次性的

有没有更简单的方法

只需在
out
参数上使用
using
块;做两个陈述,而不是一个

但你的问题表明这里有一个更根本的问题。可能返回的布尔值是有意义的。听起来您打算忽略该布尔值,
使用
out参数;如果这样做是安全的,那么只需创建一个不带布尔值的返回值的版本,因为它显然没有用处


更一般地说,从工厂返回两个值的事实是一种代码味道。你能多说说你在做什么吗?可能有更好的模式可以一起使用。

将您的使用放在下一行

CreateDisposable(out CanDispose myDispose);
using (myDispose)
{

}

您需要先声明它,然后在
using
语句中使用它

CreateDisposable(out CanDispose myDispose)
using (myDispose)
{
    ....
}
您可以查看此链接以获得有关使用
的更多信息



由于使用
语句只是“try/finally”语句的一个实现,因此您可以直接使用该语句,如下所示:

   CanDispose canDispose = null;
        try
        {
            CreateDisposable(out CanDispose canDispose);
        }

        finally
        {
            canDispose?.Dispose();
        }
如果你需要多个结果 我的建议是使用一个
元组
,但看起来您想知道对象是否已成功创建,因此可能需要检查结果。在任何情况下,使用
out
都需要在不同的行上定义var

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        var factory = new DisposableFactory();
        IDisposable d;
        var success = factory.TryGetDisposable(out d);
        if (success){
            using (d) {

            }           
        }   

        using (factory.GetDisposableResults().Item2){

        }
    }   
}

public class CanDispose : IDisposable
{
    void IDisposable.Dispose(){

    }
}

public class DisposableFactory
{
    public bool TryGetDisposable(out IDisposable d)
    {
        d = new CanDispose();
        return true;
    }

    public (bool, IDisposable) GetDisposableResults()
    {
        var tup = (true, new CanDispose());
        return tup;
    }
}


用适配器包装factory方法将使您能够保持习惯于使用的语义。一致性通常是一件好事™

public void SomeFunction()
{
  var getInstance = () => {
    CreateDisposable( out CanDispose instance );
    return instance;
  };

  using ( var instance = getInstance() ) {
    // do something with your instance before it gets disposed.
  }

}


CreateDisposable
方法需要返回一个
bool
…@RufusL,我添加了一个指示性行。多次返回的原因是我将访问器返回到数据库表,它们共享相同的数据库上下文。我可以创建上下文,然后将其传递给不同的工厂,但这会使这两件事失去关联,这使得它更容易出错。@SimonParker:如果这两件事紧密地结合在一起,那么您可以创建一个一次性类来封装这两件事,并返回它。像往常一样,事情从来都不简单。工厂是一个通用工厂,可以根据请求的访问器生成不同的访问器。这意味着返回一个一次性文件需要某种形式的魔法才能从中找到正确的存取器。