C# 闭包和对外部变量的访问
Posted
技术标签:
【中文标题】C# 闭包和对外部变量的访问【英文标题】:C# closures and access to external variables 【发布时间】:2012-01-02 03:33:17 【问题描述】:我正在尝试通过调用来使用以下内容:StaticClass.DeleteObject(null, key)
。它没有像我预期的那样工作,并且 lambda 表达式中的代码抛出 NullReferenceException 因为上下文为空,这是可以理解的。我尝试将 AmazonS3Operation 的上下文参数更改为 ref,但 ReSharper 然后警告“访问修改后的闭包”。
基本上我只是想在那个辅助方法中“注入” lambda 表达式,然后调用它,如果你知道我希望它如何工作的话。这可能吗,或者如果没有,我能做些什么类似的事情?
/// <exception cref="IOException"></exception>
public static void DeleteObject(this AmazonS3Context context, string key)
AmazonS3Operation(context, () => context.Client.DeleteObject(
new DeleteObjectRequest().WithBucketName(context.CurrentBucket)
.WithKey(key)));
/// <exception cref="IOException"></exception>
private static void AmazonS3Operation(AmazonS3Context context, Action operation)
var shouldDispose = false;
try
if (context == null)
context = new AmazonS3Context();
shouldDispose = true;
operation();
catch (AmazonS3Exception e)
throw new IOException(e.Message, e);
finally
if (shouldDispose)
context.Dispose();
【问题讨论】:
【参考方案1】:我会将上下文传递给动作。将 Action 参数替换为 Action 参数。
/// <exception cref="IOException"></exception>
public static void DeleteObject(this AmazonS3Context context, string key)
context = null;
AmazonS3Operation(context, ctx => ctx.Client.DeleteObject(
new DeleteObjectRequest().WithBucketName(ctx.CurrentBucket)
.WithKey(key)));
/// <exception cref="IOException"></exception>
private static void AmazonS3Operation(AmazonS3Context context, Action<AmazonS3Context> operation)
var shouldDispose = false;
try
if (context == null)
context = new AmazonS3Context();
shouldDispose = true;
operation(context);
catch (AmazonS3Exception e)
throw new IOException(e.Message, e);
finally
if (shouldDispose)
context.Dispose();
【讨论】:
+1 我不知道谁对此投了反对票,但这是我正在考虑的确切解决方案!这是一个很好的答案。【参考方案2】:在方法中使用局部变量而不是修改你的参数:
AmazonS3Context localContext = context;
try
if (locaContext == null)
// keep using localContext...
让你的行动成为
Action<AmazonS3Context>
所以你可以传入实例而不是依赖闭包。被调用的方法已经有你想要的实例作为它的另一个参数,所以在这里使用闭包会被认为是有害的。
【讨论】:
以上是关于C# 闭包和对外部变量的访问的主要内容,如果未能解决你的问题,请参考以下文章