ডাউন কাস্টিং এর সঠিক ব্যবহার কী?


67

ডাউনকাস্টিং মানে বেস ক্লাস (বা ইন্টারফেস) থেকে সাবক্লাস বা লিফ ক্লাসে কাস্টিং।

আপনি যদি System.Objectঅন্য কোনও ধরণের থেকে কাস্ট করেন তবে ডাউনসকাস্টের উদাহরণ হতে পারে ।

ডাউনকাস্টিং অপ্রিয়, সম্ভবত একটি কোডের গন্ধ: অবজেক্ট ওরিয়েন্টড মতবাদটি পছন্দ করা উদাহরণস্বরূপ, ডাউনকাস্টিংয়ের পরিবর্তে ভার্চুয়াল বা বিমূর্ত পদ্ধতি সংজ্ঞায়িত করা এবং কল করা।

  • ডাউনকাস্টিংয়ের জন্য ভাল এবং যথাযথ ব্যবহারের ক্ষেত্রে কী কী? এটি হ'ল, কোন পরিস্থিতিতে (গুলি) কোডকে নিম্নোক্তভাবে লিখতে উপযুক্ত?
  • যদি আপনার উত্তরটি "কেউ নয়", তবে ভাষাটি কেন ডাউন কাস্টিং সমর্থন করে?

5
আপনি যা বর্ণনা করেন তাকে সাধারণত "ডাউনকাস্টিং" বলা হয়। এই জ্ঞান নিয়ে সজ্জিত, আপনি কি নিজের নিজের সম্পর্কে আরও কিছু গবেষণা করতে পারেন এবং যে কারণগুলি খুঁজে পেয়েছেন তা পর্যাপ্ত নয় বলে ব্যাখ্যা করতে পারেন? টিএল; ডিআর: ডাউন কাস্টিং স্ট্যাটিক টাইপিংকে ভেঙে দেয় তবে কখনও কখনও টাইপ সিস্টেমটি খুব বাধা দেয় is সুতরাং কোনও ভাষার পক্ষে নিরাপদ ডাউনকাস্টিং অফার করা বুদ্ধিমানের।
আমন

আপনি কি ডাউন কাস্টিং মানে? আপকাস্টিং ক্লাসের স্তরক্রমের মধ্য দিয়ে হবে, অর্থাৎ সাবক্লাস থেকে সুপারক্লাস পর্যন্ত,
ডাউন কাস্টিংয়ের

আমার ক্ষমা: আপনি ঠিক বলেছেন। আমি প্রশ্নটি "আপকাস্ট" নামকরণ করে "ডাউনকাস্ট" এ সম্পাদনা করেছি।
ক্রিসডাব্লু

@amon en.wikipedia.org/wiki/Downcasting "STRING রূপান্তর" একটি উদাহরণ হিসাবে (যা নেট একটি ভার্চুয়াল ব্যবহার সমর্থন দেয় ToString); এর অন্য উদাহরণ "জাভা পাত্রে" কারণ জাভা জেনেরিকগুলি সমর্থন করে না (যা সি # করে)। stackoverflow.com/questions/1524197/downcast- and-upcast ডাউনকাস্টিং কী তা বলে , তবে কখন উপযুক্ত হয় তার উদাহরণ ছাড়াই ।
ক্রিসডাব্লু

4
@ChrisW এটা before Java had support for genericsনা because Java doesn't support generics। এবং অ্যামন আপনাকে উত্তরটি প্রদান করেছিল - যখন আপনি যে ধরণের সিস্টেমের সাথে কাজ করছেন তা খুব বাধাজনক এবং আপনি এটি পরিবর্তন করার মতো অবস্থানে নেই।
Ordous

উত্তর:


12

এখানে ডাউনকাস্টিংয়ের কিছু সঠিক ব্যবহার রয়েছে।

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

Equals:

class A
{
    // Nothing here, but if you're a C++ programmer who dislikes object.Equals(object),
    // pretend it's not there and we have abstract bool A.Equals(A) instead.
}
class B : A
{
    private int x;
    public override bool Equals(object other)
    {
        var casted = other as B;  // cautious downcast (dynamic_cast in C++)
        return casted != null && this.x == casted.x;
    }
}

Clone:

class A : ICloneable
{
    // Again, if you dislike ICloneable, that's not the point.
    // Just ignore that and pretend this method returns type A instead of object.
    public virtual object Clone()
    {
        return this.MemberwiseClone();  // some sane default behavior, whatever
    }
}
class B : A
{
    private int[] x;
    public override object Clone()
    {
        var copy = (B)base.Clone();  // known downcast (static_cast in C++)
        copy.x = (int[])this.x.Clone();  // oh hey, another downcast!!
        return copy;
    }
}

Stream.EndRead/Write:

class MyStream : Stream
{
    private class AsyncResult : IAsyncResult
    {
        // ...
    }
    public override int EndRead(IAsyncResult other)
    {
        return Blah((AsyncResult)other);  // another downcast (likely ~static_cast)
    }
}

আপনি যদি এগুলি কোডের গন্ধ বলে বলতে চলেছেন তবে তাদের জন্য আপনাকে আরও ভাল সমাধান সরবরাহ করতে হবে (এমনকি অসুবিধার কারণে এড়ানো গেলেও)। আমি বিশ্বাস করি না এর থেকে আরও ভাল সমাধান রয়েছে।


9
"কোড গন্ধ" এর অর্থ এই নয় যে "এই নকশাটি অবশ্যই খারাপ " এর অর্থ "এই নকশাটি সন্দেহজনক "। যে ভাষা বৈশিষ্ট্যগুলি অন্তর্নিহিত সন্দেহজনক তা ভাষা লেখকের পক্ষ থেকে বাস্তববাদিতার বিষয়
কালেথ

5
@ ক্যালাথ: এবং আমার সম্পূর্ণ বক্তব্যটি হ'ল এই নকশাগুলি সর্বদা উঠে আসে এবং আমি যে নকশাগুলি দেখিয়েছি সে সম্পর্কে জড়িত সন্দেহজনক কিছু নেই এবং তাই কাস্টিং কোনও কোডের গন্ধ নয়।
মেহরদাদ

4
@ ক্যালথ আমি একমত নই কোড গন্ধ, আমার কাছে, এর অর্থ কোডটি খারাপ বা খুব কমপক্ষে উন্নত হতে পারে।
কনরাড রুডলফ

6
@ মেহরদাদ আপনার মতামত থেকে মনে হচ্ছে কোড গন্ধটি অ্যাপ্লিকেশন প্রোগ্রামারদের দোষ হতে পারে। কেন? প্রতিটি কোড গন্ধ একটি আসল সমস্যা হতে পারে বা একটি সমাধান আছে। মার্টিন ফোলার অনুসারে একটি কোড গন্ধ হ'ল "একটি পৃষ্ঠের ইঙ্গিত যা সাধারণত সিস্টেমের গভীর সমস্যাগুলির সাথে মিলে যায়" object.Equalsবর্ণনাকে পুরোপুরি ফিট করে (সঠিকভাবে একটি সুপারক্লাসে সমান চুক্তি সরবরাহের চেষ্টা করুন যা সাবক্লাসগুলি সঠিকভাবে এটি প্রয়োগ করতে দেয় - এটি একেবারে একেবারে অ তুচ্ছ)। অ্যাপ্লিকেশন প্রোগ্রামার হিসাবে আমরা এটি সমাধান করতে পারি না (কিছু ক্ষেত্রে আমরা এড়াতে পারি) এটি একটি ভিন্ন বিষয়।
ভু

5
@ মেহরদাদ আচ্ছা আসুন দেখে নেওয়া যাক সমান ভাষা সম্পর্কে মূল ভাষা ডিজাইনারদের মধ্যে Object.Equals is horrid. Equality computation in C# is completely messed upকী বক্তব্য রাখেন .. (তার উত্তরে এরিকের মন্তব্য)। এটি মজাদার যে আপনি নিজের মতামতটি পুনর্বিবেচনা করতে চান না এমনকি এমন কি ভাষাটির একজন প্রধান ডিজাইনার নিজেই আপনাকে ভুল বলছেন।
ভু

135

ডাউনকাস্টিং অপ্রিয়, সম্ভবত একটি গন্ধযুক্ত

আমি একমত নই ডাউন কাস্টিং অত্যন্ত জনপ্রিয় ; রিয়েল-ওয়ার্ল্ড প্রোগ্রামগুলির একটি বিশাল সংখ্যায় এক বা একাধিক ডাউনকাস্ট থাকে। আর তা না হয় হয়তো একটি কোড গন্ধ। এটি অবশ্যই একটি কোড গন্ধ। যে কারণে ডাউন কাস্টিং অপারেশনটি প্রোগ্রামের পাঠ্যে প্রকাশিত হওয়া প্রয়োজন । এটি যাতে আপনি আরও সহজেই গন্ধটি লক্ষ্য করতে পারেন এবং এতে কোড পর্যালোচনা মনোযোগ ব্যয় করতে পারেন।

কোন পরিস্থিতিতে [গুলি] কোডটি নিম্নোক্তভাবে লিখতে উপযুক্ত?

যে কোনও পরিস্থিতিতে যেখানে:

  • আপনার এক্সপ্রেশনের রানটাইম টাইপ সম্পর্কে একটি সত্যের 100% সঠিক জ্ঞান রয়েছে যা এক্সপ্রেশনের সংকলন-সময়ের ধরণের চেয়ে বেশি নির্দিষ্ট এবং এবং
  • সংকলন-সময়ের ধরণে অবজেক্টের সক্ষমতা উপলব্ধ না করার জন্য আপনাকে সেই সত্যটি কাজে লাগাতে হবে এবং
  • প্রথম দুটি পয়েন্ট যে কোনওটি বাদ দেওয়ার জন্য প্রোগ্রামটি রিফ্যাক্টরের চেয়ে কাস্ট লেখার জন্য সময় এবং প্রচেষ্টার আরও ভাল ব্যবহার।

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

কেন ডাউন কাস্টিং ভাষা সমর্থন করে?

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

এছাড়াও, ডাউন কাস্টিং সি # তে খুব নিরাপদ। আমাদের দৃ strong় গ্যারান্টি আছে যে ডাউনটাইমটি রানটাইমের সময় যাচাই করা হবে এবং যদি এটি যাচাই করা যায় না তবে প্রোগ্রামটি সঠিক জিনিসটি এবং ক্র্যাশ করে। এটা চমৎকার; এর অর্থ হ'ল শব্দার্থবিজ্ঞানের বিষয়ে যদি আপনার 100% সঠিক বোঝাটি 99.99% সঠিক হয়ে যায়, তবে আপনার প্রোগ্রামটি সময়কালের 99.99% কাজ করে এবং অপ্রত্যাশিত আচরণ করার পরিবর্তে এবং ব্যবহারকারীর ডেটা ০.০১% নষ্ট করার পরিবর্তে বাকি সময় ক্রাশ করে ।


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


101
দেয়ালগুলিতে হাইস্কুলের সেই পোস্টারগুলি মনে রাখবেন "যা জনপ্রিয় তা সর্বদা সঠিক হয় না, কোনটি সঠিক তা সবসময় জনপ্রিয় হয় না?" আপনি ভেবেছিলেন যে তারা আপনাকে মাদক সেবন বা উচ্চ বিদ্যালয়ে গর্ভবতী হওয়া থেকে বিরত রাখার চেষ্টা করছে তবে তারা প্রকৃত technicalণের gersণের বিপদ সম্পর্কে সতর্কতা ছিল।
কর্সিকা

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

18
এই ব্যাখ্যাটি আমার দিনকে পরিণত করেছিল। একজন শিক্ষক হিসাবে, আমাকে প্রায়শই জিজ্ঞাসা করা হয় কেন সি # এইভাবে বা সেভাবে ডিজাইন করা হয়েছে এবং আমার উত্তরগুলি প্রায়শই আপনি এবং আপনার সহকর্মীরা এখানে এবং আপনার ব্লগগুলিতে ভাগ করে নিয়েছেন এমন অনুপ্রেরণের উপর ভিত্তি করে থাকে। "তবে কেনো ??" ফলোআপ প্রশ্নের উত্তর দেওয়া প্রায়শই কিছুটা শক্ত । এবং এখানে আমি নিখুঁত ফলোআপ উত্তরটি খুঁজে পেয়েছি: "সি # এমন ব্যবহারিক প্রোগ্রামারদের দ্বারা উদ্ভাবিত হয়েছিল যাদের কাজ করার জন্য প্র্যাকম্যাটিক প্রোগ্রামারদের কাজ করা ছিল"। :-) আপনাকে ধন্যবাদ এরিকলিপার্ট!
জ্যানো

12
একদিকে: স্পষ্টত আমার উপরের মন্তব্যে আমি বলতে চাইছিলাম যে আমরা এ থেকে বি তে একটি হ্রাস পেয়েছি তবে শ্রেণিক শ্রেণিবিন্যাস নেভিগেট করার সময় আমি "আপ" এবং "ডাউন" এবং "পিতামাতা" এবং "শিশু" ব্যবহার সত্যিই পছন্দ করি না এবং আমি সেগুলি পাই আমার লেখার সব সময় ভুল। প্রকারের মধ্যে সম্পর্ক একটি সুপারসেট / সাবসেট সম্পর্ক, সুতরাং কেন এটির সাথে কোনও দিক উপরে বা নীচে যুক্ত হওয়া উচিত, আমি জানি না। এমনকি আমাকে "পিতামাতা" থেকে শুরুও করবেন না। জিরাফের পিতা-মাতা মামাল নন, জিরাফের পিতা-মাতা হলেন মিঃ এবং মিসেস জিরাফ।
এরিক লিপার্ট

9
Object.Equalsহয় ভয়ানক । সি # তে ইক্যুয়ালিটি গণনা সম্পূর্ণরূপে গন্ডগোল হয়ে গেছে , একটি মন্তব্যে ব্যাখ্যা করতে খুব গণ্ডগোল হয়েছে। সাম্যকে প্রতিনিধিত্ব করার অনেকগুলি উপায় রয়েছে; এগুলিকে বেমানান করা খুব সহজ; এটি খুব সহজ হয়, আসলে প্রয়োজন একটি সমতা অপারেটর (প্রতিসাম্য, reflexivity এবং transitivity) তৈরি করেন বৈশিষ্ট্য লঙ্ঘন করেছে বলে। আজ যদি আমি স্ক্র্যাচ থেকে কোনও টাইপ সিস্টেম ডিজাইন করি তবে সেখানে কোনও Equals(বা GetHashcodeবা ToString) কিছু থাকবে Objectনা।
এরিক লিপার্ট

33

ইভেন্ট হ্যান্ডলারের সাধারণত স্বাক্ষর থাকে MethodName(object sender, EventArgs e)। কিছু ক্ষেত্রে ইভেন্টটি কী ধরণের তা বিবেচনা ছাড়াই senderবা এমনকি ব্যবহার না করেই ঘটনা পরিচালনা করা সম্ভব sender, তবে অন্যদের senderমধ্যে ইভেন্টটি পরিচালনা করতে আরও নির্দিষ্ট ধরণের কাস্ট করতে হবে।

উদাহরণস্বরূপ, আপনার দু'জন থাকতে পারে TextBoxএবং তাদের প্রত্যেকের কাছ থেকে কোনও ইভেন্ট পরিচালনা করতে আপনি একক প্রতিনিধি ব্যবহার করতে চান। তারপরে আপনার senderএকটি কাস্ট করতে হবে TextBoxযাতে আপনি ইভেন্টটি পরিচালনা করতে প্রয়োজনীয় বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারেন:

private void TextBox_TextChanged(object sender, EventArgs e)
{
   TextBox box = (TextBox)sender;
   box.BackColor = string.IsNullOrEmpty(box.Text) ? Color.Red : Color.White;
}

হ্যাঁ, এই উদাহরণে, আপনি নিজের উপক্লাস তৈরি করতে পারেন TextBoxযা অভ্যন্তরীণভাবে এটি করেছে। যদিও সবসময় ব্যবহারিক বা সম্ভব হয় না।


2
আপনাকে ধন্যবাদ, এটি একটি ভাল উদাহরণ। TextChangedঘটনা একজন সদস্য Control- আমি ভাবছি কেন senderধরণ দেখে নেই Controlটাইপ করার পরিবর্তে object? এছাড়াও আমি ভাবছি (তাত্ত্বিকভাবে) কাঠামোটি প্রতিটি সাবক্লাসের জন্য ইভেন্টটিকে নতুনভাবে সংজ্ঞায়িত করতে পারে (যাতে উদাহরণস্বরূপ প্রেরকের ধরণ হিসাবে TextBoxইভেন্টটির একটি নতুন সংস্করণ TextBoxথাকতে পারে) ... যাতে (বা নাও) ডাউন কাস্টিং প্রয়োজন হতে পারে ( থেকে TextBox) TextBoxবাস্তবায়নের ভিতরে (নতুন ইভেন্টের ধরণের প্রয়োগ করতে), তবে অ্যাপ্লিকেশন কোডের ইভেন্ট হ্যান্ডলারের কোনও ডাউনসকেটের প্রয়োজন হবে না।
ChrisW

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

6
@ নীল ইভেন্ট সিস্টেমগুলি স্বেচ্ছাসেবী তথ্যগুলিকে স্বেচ্ছাসেবী বিষয়গুলিতে ফরোয়ার্ড করার অনুমতি দেওয়ার জন্য তৈরি করা হয়েছে। ধরণের যথার্থতার জন্য রানটাইম-চেক ব্যতীত এটি করা প্রায় অসম্ভব।
জোকার_ভিডি

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

@ কনরাড রুডল্ফ শিওর, তবে আপনি কীভাবে ইভেন্টের কাতারে স্বেচ্ছাচারী ধরণের ইভেন্টগুলি সঞ্চয় করবেন? আপনি কি কি সারিবদ্ধ থেকে মুক্তি এবং সরাসরি প্রেরণে যাচ্ছেন?
জোকার_ভিডি

17

আপনি downcasting যখন প্রয়োজন কিছু আপনি একটি supertype দেয় এবং আপনি উপপ্রকার উপর নির্ভর করে ভিন্নভাবে এটি পরিচালনা করা প্রয়োজন।

decimal value;
Donation d = user.getDonation();
if (d is CashDonation) {
     value = ((CashDonation)d).getValue();
}
if (d is ItemDonation) {
     value = itemValueEstimator.estimateValueOf(((ItemDonation)d).getItem());
}
System.out.println("Thank you for your generous donation of $" + value);

না, এটি ভাল গন্ধ না। নিখুঁত বিশ্বে Donationএকটি বিমূর্ত পদ্ধতি থাকবে getValueএবং প্রতিটি প্রয়োগকারী উপ-টাইপের একটি যথাযথ বাস্তবায়ন হবে।

তবে এই ক্লাসগুলি যদি কোনও লাইব্রেরি থেকে আসে বা আপনি পরিবর্তন করতে চান না বা চান না? তারপরে আর কোনও বিকল্প নেই।


দর্শনার্থীর ধরণটি ব্যবহার করতে এটি বেশ ভাল সময় বলে মনে হচ্ছে। বা dynamicকীওয়ার্ড যা একই ফলাফল অর্জন করে।
ব্যবহারকারী 2023861

3
@ user2023861 কোন আমি মনে করি পরিদর্শক প্যাটার্ন অনুদান উপশ্রেণী সহযোগিতা উপর নির্ভর করে - অর্থাৎ অনুদানের একটি বিমূর্ত ঘোষণা করা প্রয়োজন void accept(IDonationVisitor visitor), যা তার উপশ্রেণী নির্দিষ্ট (যেমন ওভারলোড) পদ্ধতি কল করে বাস্তবায়ন IDonationVisitor
ক্রিসডাব্লু

@ ক্রিসডব্লিউ, আপনি ঠিক সে সম্পর্কে সহযোগিতা ছাড়াই আপনি এখনও dynamicকীওয়ার্ডটি ব্যবহার করে এটি করতে পারতেন ।
ব্যবহারকারী2023861

এই বিশেষ ক্ষেত্রে আপনি অনুদানের ক্ষেত্রে একটি প্রাক্কলন মূল্যায়ন পদ্ধতি যুক্ত করতে পারেন।
ইমিগ্রিস

@ ব্যবহারকারী2023861: dynamicএখনও ডাউনস্ট্যাসিং , কেবল ধীর।
মেহরদাদ

12

এরিক লিপার্টের উত্তরে যুক্ত করার জন্য যেহেতু আমি মন্তব্য করতে পারি না ...

আপনি প্রায়শই জেনেরিকগুলি ব্যবহারের জন্য একটি এপিআইকে রিফ্যাক্টর করে ডাউন কাস্টিং এড়াতে পারেন। কিন্তু জেনেরিক্স সংস্করণ 2.0 পর্যন্ত ভাষা না যোগ করা হয় নি । সুতরাং আপনার নিজের কোডটিতে প্রাচীন ভাষার সংস্করণগুলি সমর্থন করার প্রয়োজন না থাকলেও আপনি নিজেকে উত্তরাধিকারী ক্লাসগুলি প্যারামিটারাইজড না করে ব্যবহার করতে পারেন। উদাহরণস্বরূপ, কিছু শ্রেণীর একটি পে-লোড বহন করতে সংজ্ঞায়িত করা যেতে পারে Object, যা আপনি এটির মতো জানেন যে টাইপটি আপনি এটি করতে চান।


প্রকৃতপক্ষে, কেউ বলতে পারেন যে জাভা বা সি # তে জেনেরিকগুলি মূলত আবার উপাদানগুলি ব্যবহার করার আগে সুপারক্লাসের জিনিসগুলি সঞ্চয় করতে এবং সঠিক (সংকলক-পরীক্ষিত) সাবক্লাসে ডাউন কাস্টিংয়ের আশেপাশে কেবল একটি নিরাপদ মোড়ক। (সি ++ টেম্পলেটগুলির বিপরীতে, যা সর্বদা সাবক্লাস নিজেই ব্যবহার করার জন্য কোডটি পুনরায় লিখন করে এবং তাই ডাউনকাস্ট হওয়া এড়ায় - যা প্রায়শই সংকলনের সময় এবং এক্সিকিউটেবল আকারে ব্যয় করে মেমরির কার্যকারিতা বাড়িয়ে তুলতে পারে))
২৮

4

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

"অনিরাপদ" কনস্ট্রাকশন রয়েছে যা আপনাকে সংকলকটিতে অপ্রমাণিত প্রতিবেদন তৈরি করতে সহায়তা করে। উদাহরণস্বরূপ, নিঃশর্ত কল Nullable.Value, শর্তহীন ডাউনকাস্ট, dynamicঅবজেক্টস ইত্যাদি etc. তারা আপনাকে দাবি প্রমাণ করার অনুমতি দেয় ("আমি দৃ that়ভাবে বলি যে এই বস্তুটি aএকটি String, যদি আমি ভুল হয়ে থাকি তবে একটি নিক্ষেপ করি InvalidCastException")) প্রমাণ করার প্রয়োজন ছাড়াই । এটি এমন ক্ষেত্রে কার্যকর হতে পারে যেখানে এটি প্রমাণ করা সার্থকতার চেয়ে উল্লেখযোগ্যভাবে শক্ত।

এটির অপব্যবহার ঝুঁকিপূর্ণ, ঠিক এই কারণেই সুস্পষ্ট ডাউনকাস্ট স্বরলিপিটি বিদ্যমান এবং এটি বাধ্যতামূলক; এটি সিনট্যাকটিক লবণের অর্থ একটি অনিরাপদ অপারেশনের দিকে দৃষ্টি আকর্ষণ করা। ভাষাটি অন্তর্নিহিত ডাউনকাস্টিংয়ের মাধ্যমে প্রয়োগ করা যেতে পারে (যেখানে ইনফারার্ডের ধরণটি স্পষ্ট নয়) তবে এটি এই অনিরাপদ অপারেশনটিকে আড়াল করে রাখবে, যা কাম্য নয়।


আমি অনুমান করি যে, আমি এই ধরণের "অপ্রমাণিত দৃser়তা" তৈরি করার জন্য যেখানে প্রয়োজন / পছন্দসই (যেমন ভাল অনুশীলন) এর কয়েকটি উদাহরণের জন্য [গুলি] জিজ্ঞাসা করছি।
ক্রিসডাব্লু

1
প্রতিবিম্ব অপারেশনের ফলাফল কাস্টিং সম্পর্কে কীভাবে? stackoverflow.com/a/3255716/3141234
আলেকজান্ডার

3

ডাউনকাস্টিং বেশ কয়েকটি কারণে খারাপ বলে বিবেচিত হয়। প্রাথমিকভাবে আমি মনে করি কারণ এটি বিরোধী anti

ওওপি সত্যই এটি পছন্দ করতে পারে যদি আপনি কখনও তার '' রেইসন-ডি'ত্রে 'হিসাবে হতাশ না হন যে পলিমারফিজম মানে আপনাকে যেতে হবে না

if(object is X)
{
    //do the thing we do with X's
}
else
{
    //of the thing we do with Y's
}

তুমি ঠিক কর

x.DoThing()

এবং কোডটি অটো-ম্যাজিকালি সঠিক জিনিসটি করে।

হতাশ না করার জন্য কয়েকটি 'শক্ত' কারণ রয়েছে:

  • সি ++ এ এটি ধীর।
  • আপনি যদি ভুল টাইপ চয়ন করেন তবে রানটাইম ত্রুটি পাবেন।

তবে কিছু পরিস্থিতিতে ডাউন কাস্টিংয়ের বিকল্পটি বেশ কুৎসিত হতে পারে।

ক্লাসিক উদাহরণটি হ'ল মেসেজ প্রসেসিং, যেখানে আপনি বস্তুটিতে প্রসেসিং ফাংশনটি যুক্ত করতে চান না, তবে বার্তা প্রসেসরে রেখে দিন। MessageBaseClassপ্রক্রিয়াটি করার জন্য আমার কাছে তখন এক টন অ্যারে রয়েছে, তবে সঠিক প্রসেসিংয়ের জন্য আমারও প্রতিটি টাইপের সাব টাইপ দরকার।

সমস্যাটি ঘটাতে আপনি ডাবল ডিসপ্যাচ ব্যবহার করতে পারেন ( https://en.wikedia.org/wiki/Double_dispatch ) ... তবে এতেও সমস্যা রয়েছে। অথবা আপনি এই সাধারণ কারণে ঝুঁকিতে কিছু সাধারণ কোডের জন্য কেবল ডাউনকাস্ট করতে পারেন।

জেনারিক্স আবিষ্কার হওয়ার আগে এটি ছিল। এখন আপনি বিশদটি পরে নির্দিষ্ট করে যেখানে একটি ধরণ সরবরাহ করে ডাউন কাস্টিং এড়াতে পারবেন।

MessageProccesor<T> নির্দিষ্ট পদ্ধতি অনুসারে এর পদ্ধতির পরামিতিগুলি এবং মানগুলি ফেরত দিতে পারে তবে এখনও জেনেরিক কার্যকারিতা সরবরাহ করে

অবশ্যই কেউ আপনাকে ওওপি কোড লিখতে বাধ্য করছে না এবং এমন প্রচুর ভাষা বৈশিষ্ট্য রয়েছে যা প্রদান করা হয়েছে তবে তা প্রতিবিম্বিত করার মতোই রয়েছে।


1
আমি সন্দেহ করি এটি সি ++ এ ধীরে ধীরে, বিশেষত আপনি যদি static_castপরিবর্তে এটি করেন dynamic_cast
ChrisW

"বার্তা-প্রক্রিয়াজাতকরণ" - আমি এটিকে অর্থ হিসাবে মনে করি যেমন lParamনির্দিষ্ট কিছুতে কাস্টিং । যদিও আমি নিশ্চিত না যে এটি একটি ভাল সি # উদাহরণ, তবে।
ক্রিসডাব্লু

3
@ ক্রিসডাব্লু - ঠিক আছে, হ্যাঁ, static_castসবসময় দ্রুত ... তবে আপনি যদি ভুল করেন এবং অপরিজ্ঞাত উপায়ে ব্যর্থ না হওয়ার গ্যারান্টি নেই তবে আপনি যে ধরণের প্রত্যাশা করছেন সেটি ধরণের নয়
জুলাই

@ জুলস: এটি সম্পূর্ণরূপে পয়েন্টের পাশে।
মেহরদাদ

@ মেহরদাদ, এটা ঠিক কথা। সি ++ এর সমতুল্য # কাস্ট করতে ধীর গতিতে। এবং এটি ingালাইয়ের বিরুদ্ধে traditionalতিহ্যগত কারণ। বিকল্প স্ট্যাটিক_কাস্ট সমতুল্য নয় এবং অপরিজ্ঞাত আচরণের কারণে খারাপ পছন্দ হিসাবে বিবেচিত হয়
ইওয়ান

0

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

সাধারণভাবে, আজ অবধি কিছু ব্যবহার না করা সবসময় অযথা কিছু ব্যবহারের ইঙ্গিত দেয় না ;-)


হ্যাঁ উদাহরণস্বরূপ দেখুন । নেট এ ট্যাগ সম্পত্তিটি কী ব্যবহার করে । সেখানকার উত্তরের একটিতে কেউ লিখেছেন, আমি উইন্ডোজ ফর্ম অ্যাপ্লিকেশনগুলিতে ব্যবহারকারীর কাছে নির্দেশাবলী ইনপুট করতে এটি ব্যবহার করতাম। যখন নিয়ন্ত্রণ গটফোকাস ইভেন্টটি ট্রিগার করল, তখন নির্দেশাবলী লেবেল e পাঠ্য সম্পত্তিটি আমার নিয়ন্ত্রণ ট্যাগ সম্পত্তির মান নির্ধারিত হয়েছিল যাতে নির্দেশের স্ট্রিং রয়েছে। আমার ধারণা Control( object Tagসম্পত্তি ব্যবহারের পরিবর্তে ) 'প্রসারিত' করার বিকল্প উপায় হ'ল Dictionary<Control, string>প্রতিটি নিয়ন্ত্রণের জন্য লেবেল সংরক্ষণ করার জন্য একটি তৈরি করা ।
ChrisW

1
আমি এই উত্তরটি পছন্দ করি কারণ Tagএকটি। নেট ফ্রেমওয়ার্ক শ্রেণীর একটি সর্বজনীন সম্পত্তি, যা দেখায় যে আপনি (কম বেশি বা কম) এটি ব্যবহার করার কথা।
ক্রিসডাব্লু

@ChrisW: কোনো বলার উপসংহার ভুল (বা ডান), কিন্তু মনে রাখবেন যে পঙ্কিল যুক্তি আছে, প্রকাশ্য .NET কার্যকারিতা প্রচুর যে না থাকায় হয় (বলুন, অপ্রচলিত System.Collections.ArrayList) অথবা অন্যথায় অসমর্থিত (বলুন, IEnumerator.Reset)।
মেহরদাদ

0

আমার কাজটিতে ডাউনকাস্টিংয়ের সর্বাধিক সাধারণ ব্যবহার হ'ল লিসকভের সাবস্টিটিউশন নীতিটি ভঙ্গ করে কিছু বোকা।

ধারণা করুন কোনও তৃতীয় পক্ষের লিবে একটি ইন্টারফেস রয়েছে।

public interface Foo
{
     void SayHello();
     void SayGoodbye();
 }

এবং 2 টি ক্লাস যা এটি বাস্তবায়ন করে। Barএবং QuxBarভাল আচরণ করা হয়।

public class Bar
{
    void SayHello()
    {
        Console.WriteLine(“Bar says hello.”);
    }
    void SayGoodbye()
    {
         Console.WriteLine(“Bar says goodbye”);
    }
}

তবে Quxভাল আচরণ করা হয় না।

public class Qux
{
    void SayHello()
    {
        Console.WriteLine(“Qux says hello.”);
    }
    void SayGoodbye()
    {
        throw new NotImplementedException();
    }
}

ঠিক আছে ... এখন আমার কোন পছন্দ নেই। আমি আছে অনুক্রমে চেক এবং (সম্ভবত) হতাশ টাইপ করতে আমার প্রোগ্রামটি বিপর্যয় হাঁটিয়া যেতে বন্ধ করা হচ্ছে এড়ানো।


1
এই বিশেষ উদাহরণের জন্য সত্য নয়। সাইগুডবিতে ফোন করার সময় আপনি নোটইম্প্লেমেন্টযুক্ত ধারণাটি ধরতে পারেন catch
পার ভন জুইগবার্গ

এটি অত্যধিক সরলীকৃত উদাহরণ হতে পারে তবে কিছু পুরানো সাথে কাজ করুন। নেট এপিআই কিছুটা আপনি এই পরিস্থিতিতে চলে যাবেন। কখনও কখনও কোডটি লেখার সবচেয়ে সহজ উপায় হ'ল নিরাপদ castালাই আলা var qux = foo as Qux;
রাবারডাক

0

আর একটি বাস্তব বিশ্বের উদাহরণ ডাব্লুপিএফ এর VisualTreeHelper। এটা তোলে হতাশ ব্যবহার কাস্ট করার জন্য DependencyObjectকরতে Visualএবং Visual3D। উদাহরণস্বরূপ, ভিজ্যুয়াল ট্রিহেল্পার.গেটপ্যারেন্টহতাশার ঘটনাটি ভিজ্যুয়ালট্রি ইউটিলেস হিসাবে ঘটে sএএসভিউজুয়াল হেল্পার :

private static bool AsVisualHelper(DependencyObject element, out Visual visual, out Visual3D visual3D)
{
    Visual elementAsVisual = element as Visual;

    if (elementAsVisual != null)
    {
        visual = elementAsVisual;
        visual3D = null;
        return true;
    }

    Visual3D elementAsVisual3D = element as Visual3D;

    if (elementAsVisual3D != null)
    {
        visual = null;
        visual3D = elementAsVisual3D;
        return true;
    }            

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