C# 使用带有 return 值或内联声明结果变量的语句

C# using statement with return value or inline declared out result variable

我想知道是否有一些方法可以优化 using 语句来一起声明和分配它的输出(当它是单个值时)。

例如,类似于内联声明输出参数的结果变量的新方法。

//What I am currently doing:
string myResult;
using(var disposableInstance = new myDisposableType()){
    myResult = disposableInstance.GetResult();
}

//That would be ideal
var myResult = using(var disposableInstance = new myDisposableType()){
    return disposableInstance.GetResult();
}

//That would be great too
using(var disposableInstance = new myDisposableType(), out var myResult){
    myResult = disposableInstance.GetResult();
}

感谢您的意见。

不,没有这样的捷径。你原来的做法是对的。

如果你经常这样做,你可以把它包装在一个函数中

public class Utilities 
{
    public static TReturn GetValueFromUsing<T,TReturn>(Func<T,TReturn> func) where T : IDisposable, new()
    {
        TReturn result = default(TReturn)
        using(var instance = new T())
            result = func(instance);
        return result;
    }
}

用法

var result = Utilities.GetValueFromUsing<myDisposableType,string>(x => x.GetResult());

但男人会这样 矫枉过正

using 指令不能用作 r-value,因此无法从中分配 值。

但是,这有一个特殊情况,您可以在方便的地方使用它:您可以 return using 中的结果块。

int F(int arg)
{
    using (disposable = GetObj())
    {
       return disposable.Calculate(arg);
    }
}

这种形式通常比局部变量赋值更能传达目的。您甚至可以将它变成一个模板方法,该方法将应用 using 构造,然后调用一个策略并 return 它的结果。

class Useful<TDisposable> where TDisposable : IDisposable
{
    private Func<TDisposable> Factory { get; }
    public Useful(Func<TDisposable> factory) 
    {
       this.Fatory = factory;
    }

    public TResult SafeDo<TResult>(Func<TDisposable, TResult> operation) 
    {
       using (TDisposable obj = this.Factory())
       {
           return operation(obj);
       }
    }
}

这个 class 是完全可重复使用的,它的唯一职责是确保一次性组​​件在使用时得到处理。您可以将它包装到这个包装器 class 中,而不是直接使用一次性 class 并以这种方式使用它,您将对一次性对象有严格的生命周期控制:

void Worker(Useful<MyDisposableClass> wrapper)
{
    int arg = 5;
    wrapper.SafeDo(disp => disp.Calculate(arg);
}

在这段代码中,disp 对象将被正确构造和释放。操作 arg 所需的具体参数取自闭包。

您可以使用扩展方法 "simplify" 此使用模式:

public static class Extensions {
    public static TResult GetThenDispose<TDisposable, TResult>(
        this TDisposable d, 
        Func<TDisposable, TResult> func) 
            where TDisposable : IDisposable {

        using (d) {
            return func(d);
        }
    }
}

然后你这样使用它:

string myResult = new myDisposableType().GetThenDispose(c => c.GetResult());

这很有趣,因为几天前我开始阅读 C# 中的函数式编程,第一个例子是:

public static TResult Using<TDisposable, TResult>(TDisposable disposable, Func<TDisposable, TResult> func) 
    where TDisposable : IDisposable
{
    using (disposable)
    {
        return func(disposable);
    }
}

用法:

 var result = Using(new DbConnection(), x => x.GetResult());

请注意,与发布的其他答案不同,此函数完全没有责任,但会得到 func 的结果,而不管 TDisposable