2016-09-01 15 views
6

Tak więc stworzyłem dostawcę (kilka z nich faktycznie) i zdaję sobie sprawę, że w niektórych logikach jest pewien wzorzec. Jest on powtarzany i liczyć mogę usunąć wiele linii kodu, czy mogę po prostu stworzyć tę metodę rozszerzenia: DStatyczna metoda postępowania z zerowymi zwrotami

Tak, w zasadzie to, co się dzieje, jest coś takiego:

// Get our item to be deleted 
var model = await this._service.GetAsync(id); 

// If we have nothing, throw an error 
if (model == null) 
    throw new HttpException(404, string.Format(Resources.GenericNotFound, "List item")); 

Teraz zrób to w wielu miejscach, nie tylko do usuwania, ale do aktualizacji. Chciałbym utworzyć metodę rozszerzenia, które pozwala mi zrobić coś takiego:

// Get our item to be deleted 
var model = await this._service.GetAsync(id).ThowIfNull("List item"); 

ja też potrzebuję tego do pracy z każdym rodzajem powrotnej. Tak więc w tym przypadku może to być konto konto, ale będzie dostawca, który również ma ten kod zwracając Zamówienie, ale potrzebuję metody rozszerzenia do pracy dla obu.

Myślę, że wyzwaniem jest bit asynchroniczny, ale mogę się mylić!

Ktoś wie, czy to możliwe?

+0

Well jedną z możliwości jest '(czekają this._wervice.GetAsync (id)).ThrowIfNull ("Element listy"); 'jeśli chcesz zastosować metodę rozszerzenia na jakimkolwiek' modelu' (a może nawet na 'obiekcie') zamiast' Zadanie ' – juharr

+0

Czy możesz to napisać jako przykład? – r3plica

Odpowiedz

5

Jedną z możliwości, aby uniknąć udziału asynchronicznej-czekają na to, aby praca metodę rozszerzenia typu zwrócony wewnątrz Task

public static T ThrowIfNull<T>(this T obj, string message) where T : class 
{ 
    if (obj == null) 
     throw new HttpException(404, string.Format(Resources.GenericNotFound, message)); 
    return obj; 
} 

zrobiłem metoda rozszerzenie rodzajowy jak nie wiem jaki typ model jest. Wtedy możesz po prostu użyć tego w ten sposób.

var model = (await this._service.GetAsync(id)).ThrowIfNull("List item"); 

Poprzez umieszczenie await w nawiasie upewnić będzie czekać na zadaniu i rozpakowanie go przed przekazaniem wynik metody wydłużania.

Innym rozwiązaniem byłoby, aby uczynić pracę metody rozbudowa na Task<T>

public static async Task<T> ThrowIfNullAsync<T>(this Task<T> task, string message) 
where T : class 
{ 
    var obj = await task; 
    if (obj == null) 
     throw new HttpException(404, string.Format(Resources.GenericNotFound, message)); 
    return obj; 
} 

I nie musiałby nawias.

var model = await this._service.GetAsync(id).ThrowIfNullAsync("List item"); 

Ale to oznacza, że ​​wyjątek jest teraz zawarty w zadaniu, które może być pożądane lub nie, w zależności od sposobu korzystania z tej metody.

+0

Nie trzeba im nadawać różnych nazw, wystarczy, że będą używać tych samych nazw i będą przeciążać się nawzajem, tak samo działa funkcja 'Task.Run'. W ten sposób możesz użyć 'ThrowIfNull' zarówno dla metod synchronicznych, jak i asynchronicznych. –

+0

@ScottChamberlain Prawda, ale osobiście subskrybuję filozofię nazywania metod asynchronicznych inaczej. – juharr

+0

ja też juharr, dziękuję za to :) – r3plica

3

Można zdefiniować metodę rozszerzenia na dowolnym T:

public static class GenericExtensions 
{ 
    public static T ThrowIfNull<T>(this T obj, string message) 
    { 
     if (obj == null) 
      throw new HttpException(404, 
       string.Format(Resources.GenericNotFound, message)); 
     return obj; 
    } 
} 

Jeśli nie dbam o rodzaju powrotnej można wykorzystać object, ale że będzie ponosić boks dla typów wartości (nie wiem, ja skorzystać z tej rzeczywistości):

public static class ObjectExtensions 
{ 
    public static void ThrowIfNull(this object obj, string message) 
    { 
     if (obj == null) throw new ArgumentNullException(message); 
    } 
} 

a następnie używać go w dowolnym Zwraca typ:

async Task SomeAsyncMethod() 
{ 
    (await Foo()).ThrowIfNull("hello"); 
} 

public Task<int> Foo() 
{ 
    return Task.FromResult(0); 
} 
0

I stworzył metodę tak:

/// <summary> 
/// Throws a 404 Not found exception 
/// </summary> 
/// <param name="model">The model to check</param> 
/// <param name="name">The name to display in the message</param> 
/// <returns></returns> 
public static T ThrowIfNotFound<T>(this T model, string name) 
{ 

    // If we have nothing, throw an error 
    if (model == null) 
     throw new HttpException(404, string.Format(Resources.GenericNotFound, name)); 

    // Return our model 
    return model; 
} 
Powiązane problemy