সি # 7 তে "চেষ্টা" পদ্ধতি লেখার সর্বাধিক মার্জিত উপায় কী?


21

আমি এক প্রকার কুইউ প্রয়োগকরণ লিখছি যাতে এমন একটি TryDequeueপদ্ধতি রয়েছে যা বিভিন্ন .NET TryParseপদ্ধতির অনুরূপ প্যাটার্ন ব্যবহার করে, যেখানে আমি পদক্ষেপটি সফল হলে যদি একটি বুলিয়ান মান outফিরিয়ে দিয়েছি এবং প্রকৃত শুল্কযুক্ত মানটি ফিরে পেতে একটি পরামিতি ব্যবহার করি।

public bool TryDequeue(out Message message) => _innerQueue.TryDequeue(out message);

এখন, আমি outযখনই পারব প্যারামগুলি এড়াতে পছন্দ করি। সি # 7 তাদের সাথে কাজ করা আরও সহজ করার জন্য আমাদের পরিবর্তনশীল ডিক্লেয়ারেশনস সরবরাহ করে তবে আমি এখনও একটি কার্যকর সরঞ্জামের চেয়ে প্রয়োজনীয় অপরিহার্য বিষয়গুলি বিবেচনা করি।

এই পদ্ধতিটি থেকে আমি যে আচরণটি চাই তা নীচে:

  • যদি কোনও আইটেম প্রাপ্য হয় তবে তা ফিরিয়ে দিন।
  • যদি শনাক্ত করার মতো কোনও আইটেম না থাকে (সারিটি খালি), উপযুক্তভাবে কাজ করার জন্য কলারকে পর্যাপ্ত তথ্য সরবরাহ করুন।
  • কোনও আইটেম বাকি না থাকলে কেবল কোনও নাল আইটেমটি ফিরিয়ে দেবেন না।
  • খালি সারি থেকে বেরিয়ে আসার চেষ্টা করা হলে একটি ব্যতিক্রম ছুঁড়বেন না।

এই মুহুর্তে, এই পদ্ধতির একজন কলার প্রায় সবসময় নীচের মতো একটি প্যাটার্ন ব্যবহার করবেন (সি # 7 আউট ভেরিয়েবল সিনট্যাক্স ব্যবহার করে):

if (myMessageQueue.TryDequeue(out Message dequeued))
    MyMessagingClass.SendMessage(dequeued)
else
    Console.WriteLine("No messages!"); // do other stuff

যা সবচেয়ে খারাপ নয়, সবাই বলেছে। তবে আমি সাহায্য করতে পারছি না তবে অনুভব করতে পারি যে এটি করার ভাল উপায় আছে (আমি স্বীকার করতে পুরোপুরি ইচ্ছুক যে সেখানে নাও থাকতে পারে)। আমি ঘৃণা করি কীভাবে আহ্বানকারীকে শর্তসাপেক্ষে এটির প্রবাহটি ভেঙে ফেলতে হবে যখন তার উপস্থিতিগুলির একটিই বিদ্যমান থাকলে মান পেতে পারে।

এই একই "চেষ্টা" আচরণ সম্পাদন করার জন্য বিদ্যমান আরও কিছু নিদর্শন কী কী?

প্রসঙ্গে, এই পদ্ধতিটি সম্ভাব্যভাবে ভিবি প্রকল্পগুলিতে ডাকা হতে পারে, তাই এমন কোনও জিনিসের জন্য বোনাস পয়েন্ট যা উভয় ক্ষেত্রেই দুর্দান্ত কাজ করে। যদিও এই সত্যটি খুব কম ওজন বহন করা উচিত।


9
একটি Option<T>কাঠামো সংজ্ঞায়িত করুন এবং এটি ফিরিয়ে দিন। এই bool Try(..., out data)ফাংশনগুলি একটি ঘৃণা।
কোডসইনচাওস 16'17

2
আমি অনুরূপ চিন্তা করছিলাম ... সম্ভবত <T>, বিকল্প <T> যদি কেউ OUT পরামিতিগুলির সাথে বিরূপ থাকে।
জন রায়নোর

1
@ ফ্রাস্ট্রেটেড উইথফোর্ডস ডিজাইনার ভাল, আমি অন্যান্য বিষয়গুলিতে এতটা "চেষ্টা" করি নি (পাংস স্বাগত জানানো হয়), এতটা চিন্তা করার মতো। আমার কাছে একটি ভ্যালুটাইপল ফেরত দেওয়ার ধারণা ছিল তবে সর্বোপরি আমি মনে করি না যে এটির বেশি উন্নতি হয়েছে।
এরিক সোনারগার্ড

@ কোডসআইনচোওস আমরা একই পৃষ্ঠায় আছি, এজন্য আমি এখানে আছি! এবং আমি এই ধারণা পছন্দ করি। আপনার যদি সময় থাকে তবে আপনি কি উত্তরে আরও কিছু বিশদ দেওয়ার যত্ন নেবেন যাতে আমি তা গ্রহণ করতে পারি?
এরিক সোনারগার্ড

উত্তর:


24

একটি বিকল্প ধরণ ব্যবহার করুন, যার অর্থ দুটি ধরণের একটি ধরণের একটি অবজেক্ট বলতে বলা হয়, সাধারণত "কিছু" (যখন কোনও মান উপস্থিত থাকে) বা "কিছুই হয় না" বলা হয় ... বা মাঝে মাঝে তাদের বলা হয় জাস্ট অ্যান্ড কিছুই না। এরপরে এই ধরণের ফাংশন রয়েছে যা উপস্থিত থাকলে মানটি অ্যাক্সেস করতে দেয়, উপস্থিতির জন্য পরীক্ষা করে এবং সর্বাগ্রে গুরুত্বপূর্ণ একটি পদ্ধতি যা আপনাকে এমন একটি ফাংশন প্রয়োগ করতে দেয় যা উপস্থিত থাকলে মানটিতে আরও একটি বিকল্প প্রদান করে (সাধারণত সি # তে এটি হওয়া উচিত) ফ্ল্যাটম্যাপ বলা হবে যদিও অন্য ভাষায় এটি প্রায়শই বিন্দু পরিবর্তে বলা হয় ... নামটি সি # তে সমালোচিত কারণ এই নামটির পদ্ধতি রয়েছে এবং টাইপ করুন আপনি লিনকিউ বিবৃতিতে আপনার অপশন অবজেক্টগুলি ব্যবহার করুন)।

অতিরিক্ত বৈশিষ্ট্যগুলির মধ্যে প্রাসঙ্গিক অবস্থার সাথে ক্রিয়াকলাপের জন্য ifPstream এবং ifNotPstream এর মতো পদ্ধতি এবং ওরেলেস (কোনও মান উপস্থিত না থাকলে অন্যথায় কোনও বিকল্প নেই) এর ফলে ডিফল্ট মানকে প্রতিস্থাপন করে) ইত্যাদিও অন্তর্ভুক্ত থাকতে পারে।

আপনার উদাহরণটি তখন এর মতো দেখতে পারে:

myMessageQueue.TryDeque()
    .IfPresent( dequeued => MyMessagingClass.SendMessage(dequeued))
    .IfNotPresent (() =>  Console.WriteLine("No messages!")

এটি অপশন (বা হতে পারে) মোনাড প্যাটার্ন এবং এটি অত্যন্ত কার্যকর। বিদ্যমান বাস্তবায়ন রয়েছে (যেমন https://github.com/nlkl/Optional/blob/master/README.md ) তবে এটি আপনার নিজের পক্ষেও কঠিন নয়।

(আপনি এই প্যাটার্নটি প্রসারিত করতে ইচ্ছুক হতে পারেন যাতে পদ্ধতিটি ব্যর্থ হলে আপনি কিছুই না করে ত্রুটির কারণের বিবরণ ফিরিয়ে আনতে পারেন ... এটি সম্পূর্ণরূপে অর্জনযোগ্য এবং প্রায়শই হয় মোনাদ নামে অভিহিত হয়; নামটি বোঝা যায় আপনি একই ফ্ল্যাটম্যাপ ব্যবহার করতে পারেন সেই ক্ষেত্রে এর সাথে কাজ করা সহজ করার জন্য প্যাটার্নও)


এটি অবশ্যই একটি ভাল বিকল্প, পরামর্শ এবং আপনার ধারণার জন্য ধন্যবাদ। আমি সত্যিই এখানে আরও ধারণা অন্বেষণ করতে খুঁজছেন ছিল।
এরিক সোনারগার্ড

2
সম্পর্কে চমৎকার জিনিস Option/ Maybeযে এটি একটি একসংখ্যা হয় (যদি, এক হিসাবে প্রয়োগ করা অবশ্যই), যার মানে এটি নিরাপদে, শৃঙ্খলিত করা যায় মোড়ে, মোড়ানো, এবং প্রক্রিয়া কি কখনো সরাসরি বিভিন্ন ক্ষেত্রে পরিচালনা করতে ছাড়াই হয়, এবং এই chaining এবং LINQ ক্যোয়ারী এক্সপ্রেশন দিয়ে প্রসেসিং করা যায়।
জার্গ ডব্লু মিটাগ

3
যাইহোক, flatMap/ নেট bindডাকা SelectManyহয়।
জার্গ ডব্লু মিটাগ

5
আমি আশ্চর্য হয়েছি যে অন্য কোনও নামটি বেছে নেওয়া আরও ভাল ধারণা হবে, যেহেতু এটি করে আপনি Try...। নেট (এবং সম্ভাব্য বিভ্রান্তিকর রক্ষণাবেক্ষণকারী) নামকরণের সম্মেলনগুলি ভঙ্গ করছেন ।
বব

@ বোবি এটি একটি দুর্দান্ত বিষয়। আমি রাজী.
এরিক সোনারগার্ড

12

প্রদত্ত উত্তরগুলি ভাল এবং আমি তাদের একটির সাথে যাব। এই উত্তরটি কয়েকটি বিকল্প ধারণার সাথে কয়েকটি কোণে পূরণ করার জন্য বিবেচনা করুন:

  • Messageডাকা SomeMessageএবং এর সাবক্লাস তৈরি করুন NoMessageDequeueএখন NoMessageকোনও বার্তা না থাকলে এবং SomeMessageযদি কোনও বার্তা থাকে তবে ফিরে আসতে পারেন । যদি কলি যত্ন করে যে তারা কোন ক্ষেত্রে রয়েছে, তারা সহজেই টাইপ পরিদর্শন করে এটি করতে পারে। যদি সেগুলি না করে, তবে এর NoMessageকোনও পদ্ধতি যখনই বলা হয় কেবল তখনই কিছুই না করে এবং আরে, তারা যা চেয়েছিল তা পেয়ে যায়।

  • উপরের মত একই, তবে Messageস্পষ্টত রূপান্তরযোগ্য bool(বা বাস্তবায়ন operator true / operator false) করুন। এখন আপনি বলতে পারেন if (message)এবং এটি সত্য হতে পারে যদি বার্তাটি ভাল হয় এবং এটি খারাপ হয়। (এটি প্রায় অবশ্যই একটি খারাপ ধারণা, তবে আমি এটি সম্পূর্ণতার জন্য অন্তর্ভুক্ত করছি!)

  • সি # 7 টি টিপলস রয়েছে। একটি (bool, Message)tuple ফিরে ।

  • করুন Messageএকটি struct টাইপ এবং বিনিময়ে Message?


আরে, আপনার উত্তরের জন্য ধন্যবাদ। এই প্রশ্নটি দিয়ে আমি আমার নির্দিষ্ট সমস্যার সমাধান খুঁজে পাওয়ার জন্য যতটা চেষ্টা করেছিলাম নিজেকে বিভিন্ন ধারণার কাছে প্রকাশ করার চেষ্টা করছিলাম। চিয়ার্স!
এরিক সানডারগার্ড

আমি বলতে চাইছি যদি আপনার "খারাপ ধারণা" ইউনিটি ব্যবহার করে তবে আমরা কেন এটি ব্যবহার করতে পারি না?
আর্তুরো টরেস সানচেজ

@ আর্টুরো টরেস সানচেজ: আপনার প্রশ্নটি "অন্য কেউ সত্যিই খারাপ প্রোগ্রামিং অনুশীলন ব্যবহার করেছিলেন, তবে আমি কেন পারব না?" প্রশ্নটি অন্তর্নিহিত। অন্য কারও মতো খারাপ প্রোগ্রামিং অনুশীলনগুলি ব্যবহার করতে আপনাকে কেউ বাধা দিচ্ছে না। আপনি ঠিক এগিয়ে যান। এটি সি # তে এটি একটি ভাল অনুশীলন করবে না।
এরিক লিপার্ট

এটি গালে জিহ্বা ছিল। আমার ধারণা এটি চিহ্নিত করতে আমার "/ s" ব্যবহার করা দরকার।
আর্টুরো টরেস সানচেজ

@ আরতুরো টরেস সানচেজ: এটি একটি প্রশ্নোত্তর সাইট; আমি প্রশ্নগুলিকে এমন প্রশ্ন হিসাবে বিবেচনা করি যা উত্তর খুঁজছেন
এরিক লিপার্ট

10

সি # 7 এ আপনি আরও মার্জিত উপায়ে একই অর্জনের জন্য প্যাটার্ন মিলটি ব্যবহার করতে পারেন:

if (myMessageQueue.TryDequeue() is Message dequeued) 
{
     MyMessagingClass.SendMessage(dequeued)
} 
else 
{
    Console.WriteLine("No messages!"); // do other stuff
}

যদিও এই বিশেষ ক্ষেত্রে, আমি বারবার কাতারে ভোট দেওয়ার পরিবর্তে সম্ভবত ইভেন্টগুলি ব্যবহার করব।


3
এটি কি বাস্তবায়নের TryDequeueসাথে কিছু মার্কার ইন্টারফেস Messageএবং কিছু "কিছুই না" বাস্তবায়নের জন্য ফিরে আসে? অবশ্যই, এটি কল-সাইটে আরও মার্জিত, তবে আপনি প্রকৃত কোডে 3 টি বাস্তবায়ন বাস্তবায়ন করতে আটকে রয়েছেন, যা Messageবিদ্যমান ধরণের হলে নিজেই অসম্ভব হতে পারে ।
তেলস্তিন

1
@ টেলাস্টিন: এটি যদি কেবল শূন্য হয় তবে এটিও কাজ করে । আপনি একটি বিকল্প ধরণও ব্যবহার করতে পারেন।
জ্যাকবিবি

@ জ্যাক্কসবি: তবে নাল যদি একটি কার্যকর বৈধ আইটেম হয়?
JBSnorro

5

সাফল্যের মতো ব্যর্থতা (কোনও মূল্য নেই) এমন দৃশ্যের জন্য ট্রায় ... পদ্ধতিতে (কোনও পরামিতি রাখার) কোনও সমস্যা নেই।

তবে, আপনি যদি অন্যরকম কিছু করার জন্য জেদ করেন, আপনি একটি খালি বার্তা ফিরে আসতে চাইতে পারেন এবং কেবলমাত্র এটি (আপনার সমস্যা নয়) প্রেরণ করতে পারেন বা যদি আপনার বিষয়বস্তুতে কোনও বার্তা আছে কি না তা সত্যই জেনে রাখা উচিত যদি না আপনার বিবৃতি স্থগিত করে।

মনে রাখবেন যে কাউকে যে কোনওভাবে পরীক্ষা করাতে হবে। আমি যুক্তি দিয়ে বলব যে প্রশ্নটি কখন এবং কোথায় বর্তমান রয়েছে। এটি ডেকিংয়ের সময়।


আপনি একটি ভাল পয়েন্ট করা। আপনাকে এখনও পরীক্ষা করতে হবে, আপনি যা-ই করুন না কেন। সত্যি বলতে, আমি এখনও এই মুহুর্তে প্যারামিটারগুলি নিয়ে যাচ্ছি (বাস্তবে আমি এখনই একাধিক "ট্রাইডেকিউ" বাস্তবায়নগুলি কেবলমাত্র তাদের প্রত্যেকটির সাথে মিলিয়ে দেওয়ার জন্য প্রকাশ করছি)। আমি সত্যিই অন্যান্য বিকল্পগুলির সাথে আলোচনা করতে চেয়েছিলাম যা এখানে থাকতে পারে।
এরিক সানডারগার্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.