এটা সম্ভব
tl; dr - আপনি চাইলে একটি গেট-ওয়ান পদ্ধতিতে একটি সেটার দিয়ে ওভাররাইড করতে পারেন। এটি মূলত:
একটি newসম্পত্তি তৈরি করুন যা একই নাম ব্যবহার করে একটি getএবং একটি উভয়ই রয়েছে set।
আপনি যদি অন্য কিছু না করেন তবে getডেরিভেটিড ক্লাসটি যখন তার বেস টাইপের মাধ্যমে ডাকা হয় তখনও পুরানো পদ্ধতিটি ডাকা হবে। এটি ঠিক করার জন্য, একটি abstractমধ্যবর্তী স্তর যুক্ত overrideকরুন যা পুরাতন getপদ্ধতিতে এটি ব্যবহার করে নতুন getপদ্ধতির ফলাফল ফিরিয়ে দিতে বাধ্য করে ।
এটি আমাদের সাথে তার বৈশিষ্ট্যগুলির একটিরও অভাব থাকলেও get/ সহ বৈশিষ্ট্যগুলিকে ওভাররাইড করতে সক্ষম করে set।
বোনাস হিসাবে, আপনি চাইলে রিটার্নের ধরণও পরিবর্তন করতে পারেন।
যদি বেস সংজ্ঞাটি কেবলমাত্র হয় getতবে আপনি আরও উত্পন্ন রিটার্ন টাইপ ব্যবহার করতে পারেন।
যদি বেস সংজ্ঞাটি কেবলমাত্র ছিল set, তবে আপনি আমাদের থেকে একটি স্বল্প-উত্পন্ন রিটার্ন টাইপ করতে পারেন।
যদি বেস সংজ্ঞাটি ইতিমধ্যে get/ ছিল set, তবে:
সব ক্ষেত্রে, আপনি চাইলে একই রিটার্নের ধরণটি রাখতে পারেন। নীচের উদাহরণগুলি সরলতার জন্য একই রিটার্ন টাইপ ব্যবহার করে।
পরিস্থিতি: প্রাক-বিদ্যমান- getএকমাত্র সম্পত্তি
আপনার কিছু শ্রেণিবদ্ধ কাঠামো রয়েছে যা আপনি সংশোধন করতে পারবেন না। হতে পারে এটি কেবল একটি শ্রেণি, বা এটি পূর্ব-বিদ্যমান উত্তরাধিকার গাছ। যাই হোক না কেন, আপনি setকোনও সম্পত্তিতে একটি পদ্ধতি যুক্ত করতে চান , তবে পারবেন না।
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
সমস্যা: করা যাবে না সঙ্গে -only /overridegetgetset
আপনি overrideএকটি get/ setসম্পত্তি সঙ্গে করতে চান , কিন্তু এটি সংকলন হবে না।
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
সমাধান: একটি abstractমধ্যবর্তী স্তর ব্যবহার করুন
আপনি সরাসরি overrideকোনও সম্পত্তি get/ setসম্পত্তি দিয়ে না পারলে আপনি এটি করতে পারেন :
একই নামের সাথে একটি new get/ setসম্পত্তি তৈরি করুন ।
overrideধারাবাহিকতা নিশ্চিত করতে getনতুন getপদ্ধতির অ্যাক্সেসর সহ পুরানো পদ্ধতি ।
সুতরাং, প্রথমে আপনি abstractমধ্যবর্তী স্তরটি লিখুন :
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
তারপরে, আপনি ক্লাসটি লিখুন যা আগে সংকলন করে না। এটি এই সময়টি সংকলন করবে কারণ আপনি প্রকৃতপক্ষে overrideএকমাত্র getসম্পত্তিতে ইঙ্গিত দিচ্ছেন না; পরিবর্তে, আপনি newকীওয়ার্ডটি ব্যবহার করে এটি প্রতিস্থাপন করছেন ।
public class D : C
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } }
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
ফলাফল: সবকিছু কাজ করে!
স্পষ্টতই, এই হিসাবে কাজ হিসাবে ইচ্ছা D।
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
test.X = 7;
Print(test.X); // Prints "7", as intended.
সবকিছু এখনও কাজ করে হিসাবে উদ্দীষ্ট যখন দেখছেন Dসেটির বেস ক্লাস এক, যেমন যেমন Aবা B। তবে, এটি কাজ করার কারণটি কিছুটা কম সুস্পষ্ট হতে পারে।
var test = new D() as B;
//test.X = 7; // This won't compile, because test looks like a B,
// and B still doesn't provide a visible setter.
যাইহোক, এর বেস বর্গ সংজ্ঞাটি getচূড়ান্তভাবে উদ্ভূত শ্রেণীর সংজ্ঞা দ্বারা উপেক্ষা করা হয়েছে get, সুতরাং এটি এখনও সম্পূর্ণ সামঞ্জস্যপূর্ণ।
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
var baseTest = test as A;
Print(test.X); // Prints "7", as intended.
আলোচনা
এই পদ্ধতিটি setআপনাকে getএকমাত্র বৈশিষ্ট্যে পদ্ধতি যুক্ত করতে দেয় । আপনি এটি স্টাফ করতে এটি ব্যবহার করতে পারেন:
একটি মধ্যে কোনো সম্পত্তি পরিবর্তন get-only, set-only, অথবা get-and- setসম্পত্তি, এটা কি একটি বেস ক্লাসে ছিল নির্বিশেষে।
উত্পন্ন ক্লাসে কোনও পদ্ধতির রিটার্নের ধরণ পরিবর্তন করুন।
প্রধান ত্রুটিগুলি হ'ল abstract classউত্তরাধিকার গাছটিতে আরও কোডিং এবং অতিরিক্ত রয়েছে। এটি নির্মাণকারীদের সাথে কিছুটা বিরক্তিকর হতে পারে যা পরামিতিগুলি নেয় কারণ তাদের মধ্যবর্তী স্তরটিতে অনুলিপি / আটকানো হয়।