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
。
我想知道是否有一些方法可以优化 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
。