2016-09-01 5 views
6
Handhabung

So habe ich einen Provider (ein paar von ihnen tatsächlich) erstellt, und ich bin zu realisieren gibt es ein bisschen ein Muster in einigen meiner Logik. Es wird wiederholt, und ich glaube, ich viele Zeilen Code entfernen kann, wenn ich nur diese Erweiterung Methode erstellen können: DStatische Methode für null zurückkehrt

Also, im Grunde, was passiert etwas wie folgt aus:

// 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")); 

Nun, ich dies geschieht in vielen Orten, nicht nur für das Löschen, sondern für die Aktualisierung. Ich möchte eine Erweiterungsmethode schaffen, das mir so etwas zu tun erlaubt:

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

ich auch diese arbeiten müssen mit jedem Rückgabetyp. Also in diesem Fall könnte es ein Konto sein, aber es wird ein Anbieter, der diesen Code auch einen Auftrags Rückkehr hat, aber ich brauche die Erweiterungsmethode für beide zu arbeiten.

Ich denke, die Herausforderung hier der Asynchron-Bit, aber ich könnte falsch sein!

Wer weiß, ob es möglich ist?

+0

Nun ja, eine Möglichkeit ist, '(erwarten this._wervice.GetAsync (id)).ThrowIfNull ("List item"); 'wenn Sie möchten, dass die Erweiterungsmethode auf jedem' Modell' (oder vielleicht sogar auf 'Objekt') statt der' Task ' – juharr

+0

ist Könnten Sie dies als Beispiel aufschreiben? – r3plica

Antwort

5

Eine Möglichkeit, den Asynchron-warten Teil zu vermeiden, ist die Erweiterung Methode Arbeit von der Art innerhalb der 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; 
} 

Ich habe die Extension-Methode allgemein wie ich weiß nicht zurückgegeben zu machen, welche Art model ist. Dann kannst du es einfach so benutzen.

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

Durch die await in Klammern setzen Sie sicherstellen, dass es die Aufgabe warten und auspacken, bevor das Ergebnis an die Extension-Methode übergeben.

Die andere Möglichkeit wäre, die Erweiterung Methode funktioniert auf 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; 
} 

Und Sie würden die Klammer nicht benötigen.

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

Das bedeutet aber, dass die Ausnahme nun in der Task eingewickelt wird, die nicht wünschenswert sein kann oder nicht, je nachdem wie Sie diese Methode verwenden.

+0

Sie müssen sie nicht verschiedene Namen haben lassen, sie müssen nur den gleichen Namen haben und sich gegenseitig überladen, das ist die gleiche Art wie 'Task.Run' funktioniert. Auf diese Weise können Sie 'ThrowIfNull' sowohl für synchrone als auch für asynchrone Methoden verwenden. –

+0

@ScottChamberlain Das stimmt, aber ich persönlich habe die Philosophie, asynchrone Methoden anders zu benennen. – juharr

+0

ich auch juharr, danke dafür :) – r3plica

3

Sie können eine Erweiterungsmethode auf jedem T definieren:

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; 
    } 
} 

Wenn Sie nicht über den Rückgabetyp egal Sie object verwenden können, aber das wird Boxen für Werttypen (nicht sicher, entstehen würde ich verwenden, um dies tatsächlich):

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

und dann verwenden, auf jedem Rückgabetyp:

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

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

ich eine Methode wie folgt erstellt:

/// <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; 
} 
Verwandte Themen