2012-01-02 2 views
1

Я пытаюсь использовать следующие вызовы: StaticClass.DeleteObject(null, key). Он не работал так, как я ожидал, и код в выражении лямбда бросает исключение NullReferenceException, потому что контекст является нулевым, что понятно. Я попытался изменить параметр контекста AmazonS3Operation на ref, но ReSharper затем предупреждает о «Доступ к модифицированному закрытию».Закрытие C# и доступ к внешним переменным

В основном я просто пытаюсь «ввести» лямбда-выражение в этот вспомогательный метод, а затем назовите его, если вы получите представление о том, как я хочу, чтобы он работал. Возможно ли это, или что я могу сделать, если это не так?

/// <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(); 
    } 
} 

ответ

3

Я передал бы контекст в действие. Замените параметр «Действие» параметром «Действие» <AmazonS3Context>.

 /// <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(); 
     } 
    } 
+0

+1 Я не знаю, кто это сделал, но это точное решение, о котором я думал! Это хороший ответ. –

1

Используйте локальную переменную в методе вместо модифицируя параметр:

AmazonS3Context localContext = context; 
try { 
    if (locaContext == null) { 
    // keep using localContext... 

И ваш Действие быть

Action<AmazonS3Context> 

так что вы можете передать в случае вместо того, чтобы полагаться на закрытие. Вызываемый метод уже имеет экземпляр, который вы хотите, как его другой параметр, поэтому использование закрытия здесь будет считаться вредным.

Смежные вопросы