我想知道是否有一些方法可以优化using语句来声明并将其输出分配在一起(当它是单个值时)。
例如,类似于内联新方法的东西声明了out参数的结果变量。
//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 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
。
不,没有这样的捷径。你原来的方式是对的。
如果经常这样做,你可以将它包装在一个函数中
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值,因此无法从中指定值。
但是,有一个特殊情况,您可以在方便的地方使用它:您可以从using
块中返回结果。
int F(int arg)
{
using (disposable = GetObj())
{
return disposable.Calculate(arg);
}
}
这种形式通常比局部变量赋值更好地传达目的。您甚至可以将其转换为模板方法,其中该方法将应用using
构造,然后调用策略并返回其结果。
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);
}
}
}
该类是完全可重复使用的,其唯一的责任是确保在使用时丢弃一次性部件。您可以将其包装到此包装类中,而不是直接使用一次性类,并以这种方式使用它,并且您将对一次性对象进行严格的生命周期控制:
void Worker(Useful<MyDisposableClass> wrapper)
{
int arg = 5;
wrapper.SafeDo(disp => disp.Calculate(arg);
}
在这段代码中,disp
对象将被正确构造和处理。操作arg
所需的具体参数取自闭包。