ऐसा लगता है कि ओपी का इरादा अपने मुद्दे को हल करने के लिए एक अच्छा पैटर्न ढूंढना था और वर्तमान समस्या का समाधान करना था जो वह उस समय से संघर्ष कर रहा था।
ओपी: "मैं प्रत्येक गणना को एक सहायक विधि में लपेट सकता हूं जो विफलता पर अशक्त हो जाती है, और फिर बस ??
ऑपरेटर का उपयोग करता है, लेकिन क्या ऐसा करने का एक तरीका है आम तौर पर (यानी प्रत्येक विधि के लिए एक सहायक विधि लिखने के बिना मुझे चाहिए) उपयोग)? मैंने जेनेरिक का उपयोग करके एक स्थिर विधि लिखने के बारे में सोचा है जो किसी भी विधि को किसी भी कोशिश में पकड़ता है / पकड़ता है और विफलता पर अशक्त हो जाता है, लेकिन मुझे यकीन नहीं है कि मैं इस बारे में कैसे जाऊंगा। कोई विचार? "
मैंने बहुत सारे अच्छे पैटर्न देखे जो नेस्टेड ट्राई कैच ब्लॉक्स से बचते हैं , इस फीड में पोस्ट किए गए, लेकिन उस समस्या का हल नहीं मिला जो ऊपर उद्धृत है। तो, यहाँ समाधान है:
जैसा कि ओपी ने उल्लेख किया है, वह एक आवरण वस्तु बनाना चाहता था जो null
विफलता पर लौटती है । मैं इसे फली ( अपवाद-सुरक्षित पॉड ) कहूंगा ।
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;
लेकिन क्या होगा यदि आप CalcN () फ़ंक्शन / विधियों द्वारा लौटाए गए संदर्भ प्रकार के परिणाम के लिए एक सुरक्षित पॉड बनाना चाहते हैं ।
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}";
}
तो, आप देख सकते हैं कि "जिस विधि का आप उपयोग करना चाहते हैं उसके लिए एक सहायक विधि लिखने की कोई आवश्यकता नहीं है " ।
फली के दो प्रकार (के लिए ValueTypeResult
है और ReferenceTypeResult
रों) कर रहे हैं पर्याप्त ।
यहाँ के कोड है SafePod
। यह एक कंटेनर नहीं है, हालांकि। इसके बजाय, यहValueTypeResult
एस और ReferenceTypeResult
एस दोनों के लिए एक अपवाद-सुरक्षित प्रतिनिधि रैपर बनाता है ।
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;
}
}
यह है कि आप प्रथम श्रेणी के नागरिक संस्थाओं ( नों) ??
की शक्ति के साथ संयुक्त -सहवर्ती ऑपरेटर का लाभ कैसे उठा सकते हैं ।delegate