Es scheint, dass die Absicht des OP darin bestand, ein gutes Muster für die Lösung seines Problems und die Lösung des aktuellen Problems zu finden, mit dem er in diesem Moment zu kämpfen hatte.
OP: "Ich könnte jede Berechnung in eine Hilfsmethode einbinden, die bei einem Fehler null zurückgibt, und dann einfach den ??
Operator verwenden. Es gibt jedoch eine Möglichkeit, dies allgemeiner zu tun (dh ohne für jede Methode, die ich möchte, eine Hilfsmethode schreiben zu müssen." Ich habe darüber nachgedacht, eine statische Methode mit Generika zu schreiben, die eine bestimmte Methode in einen Versuch / Fang einschließt und bei einem Fehler null zurückgibt, bin mir aber nicht sicher, wie ich vorgehen soll. Irgendwelche Ideen? "
Ich habe viele gute Muster gesehen, die verschachtelte Try-Catch-Blöcke vermeiden , die in diesem Feed veröffentlicht wurden, aber keine Lösung für das oben genannte Problem gefunden. Hier ist also die Lösung:
Wie oben erwähnt, wollte er ein Wrapper-Objekt erstellen, das null
bei einem Fehler zurückkehrt . Ich würde es einen Pod nennen ( ausnahmesicherer Pod ).
public static void Run()
{
// The general case
// var safePod1 = SafePod.CreateForValueTypeResult(() => CalcX(5, "abc", obj));
// var safePod2 = SafePod.CreateForValueTypeResult(() => CalcY("abc", obj));
// var safePod3 = SafePod.CreateForValueTypeResult(() => CalcZ());
// If you have parameterless functions/methods, you could simplify it to:
var safePod1 = SafePod.CreateForValueTypeResult(Calc1);
var safePod2 = SafePod.CreateForValueTypeResult(Calc2);
var safePod3 = SafePod.CreateForValueTypeResult(Calc3);
var w = safePod1() ??
safePod2() ??
safePod3() ??
throw new NoCalcsWorkedException(); // I've tested it on C# 7.2
Console.Out.WriteLine($"result = {w}"); // w = 2.000001
}
private static double Calc1() => throw new Exception("Intentionally thrown exception");
private static double Calc2() => 2.000001;
private static double Calc3() => 3.000001;
Was aber, wenn Sie einen sicheren Pod für ein Referenztyp-Ergebnis erstellen möchten, das von CalcN () -Funktionen / -Methoden zurückgegeben wird?
public static void Run()
{
var safePod1 = SafePod.CreateForReferenceTypeResult(Calc1);
var safePod2 = SafePod.CreateForReferenceTypeResult(Calc2);
var safePod3 = SafePod.CreateForReferenceTypeResult(Calc3);
User w = safePod1() ?? safePod2() ?? safePod3();
if (w == null) throw new NoCalcsWorkedException();
Console.Out.WriteLine($"The user object is {{{w}}}"); // The user object is {Name: Mike}
}
private static User Calc1() => throw new Exception("Intentionally thrown exception");
private static User Calc2() => new User { Name = "Mike" };
private static User Calc3() => new User { Name = "Alex" };
class User
{
public string Name { get; set; }
public override string ToString() => $"{nameof(Name)}: {Name}";
}
Möglicherweise stellen Sie fest, dass "für jede Methode, die Sie verwenden möchten, keine Hilfsmethode geschrieben werden muss" .
Die zwei Arten von Pods (für ValueTypeResult
s und ReferenceTypeResult
s) sind ausreichend .
Hier ist der Code von SafePod
. Es ist jedoch kein Container. Stattdessen wird ein ausnahmesicherer Delegate-Wrapper für ValueTypeResult
s und ReferenceTypeResult
s erstellt.
public static class SafePod
{
public static Func<TResult?> CreateForValueTypeResult<TResult>(Func<TResult> jobUnit) where TResult : struct
{
Func<TResult?> wrapperFunc = () =>
{
try { return jobUnit.Invoke(); } catch { return null; }
};
return wrapperFunc;
}
public static Func<TResult> CreateForReferenceTypeResult<TResult>(Func<TResult> jobUnit) where TResult : class
{
Func<TResult> wrapperFunc = () =>
{
try { return jobUnit.Invoke(); } catch { return null; }
};
return wrapperFunc;
}
}
So können Sie die Null-Koaleszenz nutzen Betreiber ??
mit der Kraft des kombinierten Bürger erster Klasse Einheiten ( delegate
n).