"ডেলিগেট বিয়োগের অপ্রত্যাশিত ফলাফল আছে" রিসার্পার / সি # তে?


124

myDelegate -= eventHandlerরিশার্পার (সংস্করণ 6) সমস্যাগুলি ব্যবহার করার সময় :

ডেলিগেট বিয়োগের অপ্রত্যাশিত ফলাফল রয়েছে

এর পিছনে যুক্তি এখানে জেটব্রেইনস দ্বারা ব্যাখ্যা করা হয়েছে । ব্যাখ্যাটি অর্থবহ করে এবং এটি পড়ার পরে, আমি -প্রতিনিধিদের উপর আমার সমস্ত ব্যবহার সম্পর্কে সন্দেহ করি ting

তাহলে কীভাবে ,

  • আমি কি রি-শেয়ারারকে গ্রম্পি না করে একটি অ-অটো ইভেন্ট লিখতে পারি?
  • বা, এটি বাস্তবায়নের জন্য আরও ভাল এবং / বা "সঠিক" উপায় আছে কি?
  • বা, আমি কি কেবল রিসার্পারকে উপেক্ষা করতে পারি?

এখানে সরলীকৃত কোড দেওয়া হয়েছে:

public delegate void MyHandler (object sender);

MyHandler _myEvent;

public event MyHandler MyEvent
{
    add
    {
        _myEvent += value;
        DoSomethingElse();
    }
    remove
    {
        _myEvent -= value; // <-- ReSharper warning here
    }
}

মনোও একই সতর্কতা দেয়। এখানে আর # 'গুলি সমস্যা বিবরণ confluence.jetbrains.com/display/ReSharper/... (যা শুধুমাত্র প্রতিনিধি তালিকাতে প্রযোজ্য)
thoredge

উত্তর:


134

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

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

রিশার্পার এই সতর্কতা জারি করছে কারণ মাল্টিকাস্টের প্রতিনিধি বিয়োগের ক্ষেত্রে গ্যাটাচস থাকতে পারে, এটি ভাষা বৈশিষ্ট্যটিকে পুরোপুরি নিন্দা করে না। ভাগ্যক্রমে got গোটাচাগুলি সামান্য ক্ষেত্রে রয়েছে এবং আপনি যদি কেবল সাধারণ ইভেন্টগুলি চালাচ্ছেন তবে আপনার সেগুলির মুখোমুখি হওয়ার সম্ভাবনা নেই। আপনার নিজের add/ removeহ্যান্ডলারগুলি বাস্তবায়নের আরও ভাল কোনও উপায় নেই , আপনি কেবল নোটিশ নিতে হবে take

আমি সেই বার্তাটির জন্য রিশার্পারের সতর্কতা স্তরটিকে "ইঙ্গিত" এ ডাউনগ্রেড করার পরামর্শ দিচ্ছি যাতে আপনি তাদের সতর্কতার প্রতি সংবেদনশীল না হন, যা সাধারণত দরকারী।


66
আমি মনে করি ফলাফলগুলিকে "অনাকাঙ্ক্ষিত" বললে এটি আর # এর খারাপ। তারা খুব স্পষ্টভাবে নির্দিষ্ট করা আছে। "ব্যবহারকারী যা অনুমান করতে পারে" তা কোনওভাবেই "অপ্রত্যাশিত" হিসাবে একই জিনিস নয়। (। এছাড়া বেঠিক বলতে চাই যে .NET Framework সংজ্ঞায়িত overloads - এটি C # এর কম্পাইলার মধ্যে বেকড এর Delegateনেই না জমিদার +এবং -।)
জন স্কিট

6
@ জন: আমি একমত আমার ধারণা মাইক্রোসফ্ট নিজেরাই উচ্চ সেটটিতে প্রত্যেকে অভ্যস্ত হয়ে পড়েছে। পোলিশের মাত্রা যতটা উঁচুতে থাকে, তেমন অনেক কিছু দিয়ে। নেট বিশ্বজুড়ে যে আপনাকে "সাফল্যের গর্তে পড়ে" তোলে, এমন একটি ভাষার বৈশিষ্ট্যের মুখোমুখি হয় যেখানে একটি গর্তের পাশে একটি নিখরচায় হাঁটাচলা থাকে সুযোগটি আপনি মিস করতে পারেন কেউ কেউ এটিকে ঝাঁকুনি হিসাবে বিবেচনা করে এবং একটি লক্ষণ বাণী সতর্ক করে দেয় PIT OF SUCCESS IS THAT WAY --->
অ্যালন গুরালেনেক

5
@ অ্যালন গুরালেনেক: অন্যদিকে, আপনি যখন শেষবারের মতো শুনলেন যে কারও কারও কারণে আসলেই সমস্যা হচ্ছে?
জন স্কিটি

5
@ জন: কোন সমস্যা শুনেছেন? আমি এমনকি করা হয়নি জানি এই আচরণ সম্পর্কে আগে এই প্রশ্নের পোস্ট করা হয়েছে।
অ্যালন গুরালেনেক

2
এটি আগ্রহী যে আর # প্রতিনিধি বিয়োগ সম্পর্কে সতর্ক করবে, তবে ঠিক একই সমস্যা রয়েছে এমন ইভেন্টগুলির সাধারণ বাস্তবায়ন সম্পর্কে সতর্ক করবে না । মূল সমস্যাটি হ'ল নেট একটি একক ব্যবহার করে Delegate.Combineযা বহুচলিত প্রতিনিধিদের "চাটুকার" করে, সুতরাং যদি এটির প্রতিনিধি [এক্স, ওয়াই] এবং জেড দেওয়া হয় তবে ফলাফলটি [এক্স, ওয়াই, জেড] বা [[হওয়া উচিত কিনা তা এটি বলতে পারে না এক্স, ওয়াই], জেড] (পরবর্তী প্রতিনিধি [X,Y]প্রতিনিধিটিকে তার হিসাবে ধরে রাখে Target, এবং সেই প্রতিনিধিটির Invokeপদ্ধতিটি এটি হিসাবে থাকে Method)।
সুপারক্যাট

28

আপনার সরাসরি প্রতিনিধিদের যোগফল বা বিয়োগ করতে ব্যবহার করা উচিত নয়। পরিবর্তে আপনার ক্ষেত্র

MyHandler _myEvent;

পরিবর্তে পাশাপাশি একটি ইভেন্ট হিসাবে ঘোষণা করা উচিত। এটি আপনার সমাধানটিকে ঝুঁকিতে না ফেলে সমস্যার সমাধান করবে এবং তবুও ইভেন্ট ব্যবহারের সুবিধা থাকবে।

event MyHandler _myEvent;

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

myObject.MyEvent += Method1; 
myObject.MyEvent += Method2;
myObject.MyEvent = Method3;

মেথড 3 নির্ধারণের সময়, আমি দুটি প্রাথমিক সাবস্ক্রিপশন পুরোপুরি হারিয়েছি। ইভেন্টের ব্যবহার এই সমস্যাটি এড়াবে এবং একই সাথে রিশার্পার সতর্কতাটি সরিয়ে দেবে।


আমি কখনই এটিকে করার কথা ভাবি নি, তবে যতক্ষণ আপনি এই অন্তর্নিহিত ইভেন্টটি ব্যক্তিগত রাখেন না ততক্ষণ ইভেন্টের প্রতিনিধিদের ব্যবহার রক্ষা করা কোনও অর্থবোধ করে না। এটি আরও ভাল কাজ করে না যখন আরও নির্দিষ্ট থ্রেড সিঙ্ক্রোনাইজেশন থাকে যা অবশ্যই একাধিক ইভেন্টের সাবস্ক্রিপশন বা সাব-সাবস্ক্রিপশনগুলির পাশাপাশি ট্র্যাক করার প্রয়োজন এমন হ্যান্ডলারগুলিকে অ্যাড / রিমুভ করতে হবে। তবে যে কোনও ক্ষেত্রে এটি সতর্কতাগুলি সরিয়ে দেয়।
জেরেমি 13

-17

- = ব্যবহার করার পরিবর্তে এটিকে = নালিতে সেট করুন


5
removeএকটি ইভেন্ট পদ্ধতি সব হ্যান্ডেলার অপসারণ করা উচিত নয়, বরং হ্যান্ডলার রয়েছে যা অনুরোধ করা হয়েছে অপসারণ করা হবে।
পরিবেশন করুন

যদি তিনি কেবলমাত্র যুক্ত হন তবে তিনি যদি কেবলমাত্র একটিটিকে কার্যকরভাবে সরিয়ে ফেলেন তবে সে সমস্তগুলি মুছে ফেলেছে। আমি বলছি না যে এটি কেবলমাত্র এই নির্দিষ্ট পুনরায় ভাগ করা বার্তার জন্য সমস্ত ক্ষেত্রে ব্যবহার করুন।
জোনাথন বেরেসফোর্ড

6
কিন্তু আপনি না জানি যে প্রতিনিধি সবসময় আবাহন তালিকায় শুধুমাত্র আইটেমটি মুছে দিচ্ছেন। এটি সঠিক ওয়ার্কিং কোডটিকে ভুল ভাঙ্গা কোডে পরিণত করে পুনঃভাগের বার্তাটি সরিয়ে দিচ্ছে যা কিছু পরিস্থিতিতে কাকতালীয়ভাবে কাজ করবে, তবে এটি অনেক ক্ষেত্রে অস্বাভাবিক এবং উপায় নির্ণয়ের পক্ষে শক্ত হয়ে উঠবে।
সার্ভিস করুন

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