}} স্টেটমেন্টটি ব্যবহার করে ভিতরে ফিরতে কল করা কি ভাল ধারণা?


93

আমি কেবল এটি জানতে চাই যে returnকোনও usingব্লকের অভ্যন্তরে কল করা নিরাপদ / ভাল পদ্ধতি ।

প্রাক্তন জন্য।

using(var scope = new TransactionScope())
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}

আমরা জানি সবচেয়ে শেষ কোঁকড়ানো বন্ধনী dispose()বন্ধ হয়ে যাবে। তবে উপরোক্ত ক্ষেত্রে কী হবে, যেহেতু returnপ্রদত্ত সুযোগ (এএফএআইকি) থেকে নিয়ন্ত্রণটি লাফিয়ে যায় ...

  1. আমার scope.Complete()ফোন করা হয়?
  2. এবং তাই সুযোগ এর dispose()পদ্ধতির জন্য।

4
using{}সুযোগটি শেষ হয়ে গেলে , প্রাসঙ্গিক বস্তুগুলি নিষ্পত্তি হয়ে যায়, returnসুযোগটি "ভেঙে" যাবে - সুতরাং প্রত্যাশাগুলি প্রত্যাশার মতো নিষ্পত্তি হবে
শাই

4
সচেতন হন যে আপনার scope.Complete()সরবরাহিত নমুনার সাথে আপনার কলটি কখনও আঘাত হারাবে না, তাই আপনার লেনদেন সর্বদা রোলব্যাক করবে।
অ্যান্ডি

কিনা তথাপি usingএর dispose()বলা হয়, যখন আপনি ফিরে, এই ধারণকারী ফাংশন usingব্লক ফিরে হবে এবং এটি একাত্মতার সবকিছু এতিম করা হবে না। এমনকি যদি scope"দ্বারা" নিষ্পত্তি নাও করা হয় using(এটি অন্যরা যেমন ব্যাখ্যা করেছেন) এটি যেভাবেই নিষ্পত্তি করা হবে কারণ ফাংশনটি শেষ হয়েছিল। সি # এর gotoবিবৃতি থাকলে -আপনি এখনও হাসছেন? ভাল- তারপরে ফিরে আসার পরিবর্তে আপনি gotoবন্ধ বন্ধনী পরে ফিরে আসতে পারেন । যৌক্তিকভাবে, scopeএখনও নিষ্পত্তি করা হবে, তবে আপনি কেবল gotoসি # তে রেখেছেন যাতে কে এই পর্যায়ে যুক্তির বিষয়ে চিন্তা করে।
সুপারবেস্ট


উত্তর:


148

returnআপনার usingব্লকের ভিতরে কল করা পুরোপুরি নিরাপদ , যেহেতু ব্যবহারের ব্লকটি কেবল একটি try/finallyব্লক।

প্রত্যাবর্তনের পরে উপরে আপনার উদাহরণে true, সুযোগটি নিষ্পত্তি হবে এবং মানটি ফিরে আসবে। return false, এবং কল করা scope.Complete()হবে নাDisposeতবে এটি নির্বিশেষে বলা হবে কারণ এটি অবশেষে ব্লকের ভিতরে থাকে।

আপনার কোডটি মূলত এটির মতোই (যদি এটি বুঝতে সহজ হয়):

var scope = new TransactionScope())
try
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}
finally
{
  if( scope != null) 
    ((IDisposable)scope).Dispose();
}

দয়া করে সচেতন থাকুন যে লেনদেন করার কোন উপায় নেই বলে আপনার লেনদেন কখনই প্রতিশ্রুতিবদ্ধ নাscope.Complete()


13
আপনার এটি পরিষ্কার করা উচিত যা কল Dispose হবে । ওপি যদি কী না ঘটে তা না জানায় তবে তার কী হয় usingতা সে জানে না এমন সম্ভাবনা রয়েছে finally
কনরাড রুডল্ফ

রিটার্ন সহ একটি ব্যবহারের ব্লক ছেড়ে দেওয়া ঠিক আছে তবে লেনদেনস্কোপের ক্ষেত্রে আপনি
দ্য হোয়াইটাম্বিত

আমার অভিজ্ঞতায়, এটি এসকিউএল সার্ভার সিএলআর অ্যাসেম্বলিসগুলির সাথে কাজ করে না। যখন আমাকে একটি ইউএসএফের জন্য ফলাফলগুলি ফিরে আসতে হবে যখন একটি স্ক্যুএলএক্সএমএল ক্ষেত্র রয়েছে যা একটি মেমরিস্ট্রিম অবজেক্টটি উল্লেখ করে। আমি " কোনও নিষ্পত্তিযোগ্য অবজেক্টে অ্যাক্সেস করতে পারি না " এবং " স্ট্রিমটি বন্ধ হয়ে গেলে রিডকে কল করার জন্য অবৈধ প্রচেষ্টা " পেয়েছি, সুতরাং আমি এই দৃশ্যে ফাঁস কোড লিখতে এবং ব্যবহার-বিবৃতিটি রেখে যেতে বাধ্য। :( আমার একমাত্র আশা এসকিউএল CLR এই বস্তু বিক্রয়কালে হ্যান্ডেল করা হবে, বরং এটি একটি অনন্য দৃশ্যকল্প, কিন্তু আমি ভাগ চাই
MikeTeeVee

4
@MikeTeeVee - ক্লিনার সমাধান পারেন হয় (ক) আহ্বায়ক না আছে using, যেমন using (var callersVar = MyFunc(..)) .., পরিবর্তে ভিতরে ব্যবহার "MyFunc" থাকার - স্ট্রিম হয় এবং মাধ্যমে এটি বন্ধ করার জন্য দায়ী করা হয় আমি আহ্বানকারী মানে usingবা স্পষ্টভাবে, অথবা (খ) MyFunc আছে নির্যাস তারপর অন্তর্নিহিত তথ্য বস্তু বা স্ট্রিম আপনার দ্বারা বিন্যস্ত করা যেতে পারে - আপনার যেকোনো তথ্য অন্যান্য বস্তু, যে নিরাপদে ফিরে পাশ করা যাবে মধ্যে প্রয়োজন হয় using। আপনার ফাঁস কোড লিখতে হবে না।
টুলমেকারস্টেভ

7

এটি ঠিক আছে - finallyক্লজগুলি (যা দফার ক্লোজিং কোঁকড়াটি বন্ধনী usingহুডের নীচে করে) সর্বদা সুযোগটি যখন ছেড়ে যায় তখনই তা কার্যকর করা হয়, যাই হোক না কেন।

যাইহোক, এটি কেবলমাত্র শেষ অবধিগুলিতে থাকা বিবৃতিগুলির ক্ষেত্রেই সত্য (যা ব্যবহারের সময় স্পষ্টভাবে সেট করা যায় না using)। অতএব, আপনার উদাহরণে, scope.Complete()কখনই কল করা হবে না (আমি আশা করি যে সংকলকটি অ্যাক্সেসযোগ্য কোড সম্পর্কে আপনাকে সতর্ক করার জন্য))


2

সাধারণভাবে, এটি একটি ভাল পদ্ধতির। তবে আপনার ক্ষেত্রে, আপনি যদি কল করার আগে ফিরে যান scope.Complete(), এটি কেবলমাত্র ট্রানজেকশনস্কোপ ট্র্যাশ করবে। আপনার নকশার উপর নির্ভর করে।

সুতরাং, এই নমুনায়, সম্পূর্ণ () বলা হয় না, এবং সুযোগটি নিষ্পত্তি করা হয়, ধরে নিই এটি আইডিপোজেবল ইন্টারফেস উত্তরাধিকার সূত্রে প্রাপ্ত।


এটি অবশ্যই আইডিস্পোজেবল বা স্বতন্ত্র সংকলন ব্যবহার করে প্রয়োগ করতে পারে।
Chriseyre2000

2

সুযোগ.কম্পিউট অবশ্যই অবশ্যই আগে বলা উচিত return। সংকলক একটি সতর্কতা প্রদর্শন করবে এবং এই কোডটি কখনই কল করা হবে না।

returnনিজের সম্পর্কে - হ্যাঁ, এটিকে usingস্টেটমেন্টের ভিতরে বলা নিরাপদ । ব্যবহারটি অনুবাদ করা হয়েছে অনূদিত অবশেষে দৃশ্যের পিছনে অবরুদ্ধ করার জন্য এবং অবশেষে ব্লকটি অবশ্যই কার্যকর করা হবে।


1

আপনি যে উদাহরণ সরবরাহ করেছেন তাতে একটি সমস্যা আছে; scope.Complete()কখনও বলা হয় না। দ্বিতীয়ত: returnবিবৃতিতে usingস্টেটমেন্ট ব্যবহার করা ভাল অভ্যাস নয় । নিম্নলিখিত উল্লেখ করুন:

using(var scope = new TransactionScope())
{
    //have some logic here
    return scope;      
}

এই সাধারণ উদাহরণে, কথাটি হ'ল; scopeবিবৃতি ব্যবহার শেষ হলে মানটি নাল হবে।

সুতরাং বিবৃতি ব্যবহার করে ভিতরে না ফিরে ভাল।


4
কেবল 'রিটার্ন স্কোপ' অর্থহীন, এটি বোঝায় না যে রিটার্নের বিবৃতিটি ভুল।
প্রীত সংঘ

কেবলমাত্র সেরা অভ্যাসগুলি ব্যবহার না করা বোঝায় না যে আপনি কিছু ভুল করেছেন। এটি বোঝা যায়, এড়ানো ভাল, কারণ এটি অপ্রত্যাশিত পরিণতি হতে পারে।
ডায়রিয়াল

4
এর মানটি scopeনালাগুলি হবে না - কেবল যেটি ঘটবে তা হ'ল সেই Dispose()উদাহরণটি ব্যবহার করা হবে, সুতরাং সেই উদাহরণটি আর ব্যবহার করা উচিত নয় (তবে এটি নাল নয় এবং আপনাকে চেষ্টা ও ব্যবহার করতে বাধা দেওয়ার মতো কিছু নেই) নিষ্পত্তিযোগ্য বস্তু, যদিও এটি প্রকৃতপক্ষে কোনও নিষ্পত্তিযোগ্য বস্তুর অনুপযুক্ত ব্যবহার)।
Lucero

Lucero বেশ সঠিক। নিষ্পত্তিযোগ্য বস্তুগুলি নিষ্পত্তি হওয়ার পরে শূন্য হয় না। এর আইসডিসপোজড সম্পত্তিটি সত্য, তবে আপনি যদি শূন্যের বিরুদ্ধে পরীক্ষা করেন তবে আপনি মিথ্যা হন এবং সেই বস্তুর return scopeএকটি রেফারেন্স ফিরিয়ে দেন । এইভাবে, আপনি যদি ফেরত নেওয়ার ক্ষেত্রে সেই রেফারেন্সটি অর্পণ করেন তবে আপনি জিসিকে নিষ্পত্তিযোগ্য বস্তু পরিষ্কার করতে বাধা দেন।
থান্ডারগ্রি

1

scope.Complete()যেটিকে ডাকা হবে তা নিশ্চিত করার জন্য এটি দিয়ে মুড়িয়ে দিন try/finallydisposeকারণ আপনার সাথে এটি মোড়ানো আছে বলা হয় usingএকটি বিকল্প যে try/finallyব্লক।

using(var scope = new TransactionScope())
{
  try
  {
  // my core logic
  return true; // if condition met else
  return false;
  }
  finally
  {
   scope.Complete();
  }
}

আমি মনে করি আপনি বলতে চাইলে আপনি যদি জিতেন - আপনি যদি চান তবে আপনার কোড অনুসারে হবে না ... :)

0

এই উদাহরণে স্কোপ.কমপ্লিট () কখনই কার্যকর হবে না। যাইহোক, রিটার্ন কমান্ড স্ট্যাকের মধ্যে নির্ধারিত সমস্ত কিছু পরিষ্কার করবে। জিসি অযৌক্তিক যে কোনও বিষয় যত্ন নেবে। সুতরাং, জিসি দ্বারা বাছাই করা যায় না এমন কোনও জিনিস না থাকলে কোনও সমস্যা নেই।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.