দেখে মনে হয় যে ওপি'র উদ্দেশ্য ছিল তাঁর সমস্যাটি সমাধান করার জন্য এবং সেই মুহূর্তে তিনি যে বর্তমান সমস্যাটি মোকাবেলা করেছিলেন তার সমাধানের জন্য একটি ভাল প্যাটার্ন খুঁজে বের করা।
ওপি: "আমি প্রতিটি গণনা একটি সহায়ক পদ্ধতিতে গুটিয়ে রাখতে পারি যা ব্যর্থতার পরে বাতিল হয়ে যায়, এবং তারপরে কেবল ??
অপারেটরটি ব্যবহার করে , তবে এটি আরও সাধারণভাবে করার উপায় আছে (যেমন আমি চাই প্রতিটি পদ্ধতির জন্য কোনও সহায়ক পদ্ধতি না লিখে) ব্যবহার)? আমি জেনেরিক ব্যবহার করে একটি স্ট্যাটিক পদ্ধতি লেখার কথা ভেবেছি যা কোনও চেষ্টা / ধরাতে যে কোনও পদ্ধতি আবৃত করে এবং ব্যর্থতার পরে বাতিল হয়ে যায়, তবে আমি কীভাবে এটি করব তা নিশ্চিত নই? কোন ধারণা? "
আমি প্রচুর ভাল নিদর্শন দেখেছি যা নেস্টেড ট্রায়াল ক্যাচ ব্লকগুলি এড়ানোর জন্য এই ফিডে পোস্ট করা হয়েছে, তবে উপরে বর্ণিত সমস্যাটির কোনও সমাধান খুঁজে পাইনি। সুতরাং, সমাধান এখানে:
ওপিকে উপরে উল্লিখিত হিসাবে, তিনি একটি মোড়কের বস্তু তৈরি করতে চেয়েছিলেন যা 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;
তবে আপনি যদি ক্যালসএন () ফাংশন / পদ্ধতি দ্বারা ফেরত একটি রেফারেন্স টাইপ ফলাফলের জন্য একটি নিরাপদ শুঁটি তৈরি করতে চান ।
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}";
}
সুতরাং, আপনি লক্ষ্য করতে পারেন যে "আপনি যে প্রতিটি পদ্ধতি ব্যবহার করতে চান তার জন্য একটি সহায়ক পদ্ধতি লেখার" দরকার নেই ।
Pods দুই ধরনের (জন্য ValueTypeResult
s এবং 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