কেন কেবলমাত্র গেটর-কেবল সম্পত্তিটিকে ওভাররাইড করা এবং একটি সেটার যুক্ত করা অসম্ভব? [বন্ধ]


141

নিম্নলিখিত সি # কোড কেন অনুমোদিত নয়:

public abstract class BaseClass
{
    public abstract int Bar { get;}
}

public class ConcreteClass : BaseClass
{
    public override int Bar
    {
        get { return 0; }
        set {}
    }
}

CS0546 'কংক্রিটক্লাস.বার.সেট': ওভাররাইড করতে পারে না কারণ 'বেসক্লাস.বার'-এর ওভারিডেবল সেট অ্যাক্সেসর নেই


9
মাইক্রোসফ্টের পক্ষ থেকে স্ট্যাকওভারফ্লো প্রশ্নের উত্তর দেওয়ার সীমিত ক্ষমতা রয়েছে has আপনার প্রশ্নটি পুনরায় বিবেচনা করুন।
জে বাজুজি

1
প্রসঙ্গত ,। নেট-এ এই বিরক্তিকর আচরণের একটি সহজ প্রতিকার হ'ল একটি অ-ভার্চুয়াল পঠনযোগ্য সম্পত্তি Fooযা কোনও সুরক্ষিত বিমূর্ত GetFooপদ্ধতি মোড়ানো ছাড়া কিছুই করে না । একটি বিমূর্ত উত্পন্ন প্রকারটি কোনও ভার্চুয়াল পঠন-লিখন সম্পত্তি দ্বারা সম্পত্তিটির ছায়া ফেলতে পারে যা GetFooবিমূর্ত SetFooপদ্ধতি সহ পূর্বোক্ত পদ্ধতিটি মোড়ানো ছাড়া কিছুই করে না ; একটি কংক্রিট উদ্ভূত ধরণের উপরেরটি করতে পারে তবে সরবরাহ সংজ্ঞা GetFooএবং SetFoo
সুপারক্যাট

1
কেবল আগুনে জ্বালানী যুক্ত করতে, সি ++ / সিএলআই এটির অনুমতি দেয়।
ইয়ামেট

1
কোনও প্রোপার্টি ওভাররাইড করার সময় অ্যাক্সেসর যুক্ত করার ক্ষমতাটি সি # ( github.com/dotnet/roslyn/issues/9482 ) এর ভবিষ্যতের সংস্করণের পরিবর্তনের জন্য প্রস্তাবিত হয়েছে ।
ব্র্যান্ডন বন্ডস

1
প্রকৃতপক্ষে, এই প্রশ্নটি প্রায়শই উত্থাপিত হয় যখন কোনও বিদ্যমান লাইব্রেরি ধরণের বাড়ানো দরকার যা নিম্নলিখিত প্যাটার্নটি ব্যবহার করে: কেবলমাত্র পঠনযোগ্য বেস শ্রেণি, উত্পন্ন পরিবর্তনীয় শ্রেণি। গ্রন্থাগারটি ইতিমধ্যে একটি খারাপ প্যাটার্ন ব্যবহার করেছে (যেমন ডাব্লুপিএফ), এই খারাপ প্যাটার্নটিকে একত্রিত করার প্রয়োজন দেখা দেয়। বক্তৃতা দিনের শেষে কোনও কর্মপরিকল্পনা প্রয়োগ করা থেকে বাঁচায় না।
rwong

উত্তর:


-4

কারণ বেসক্লাসের লেখক স্পষ্টভাবে ঘোষণা করেছেন যে বারটি কেবল পঠনযোগ্য সম্পত্তি হতে হবে। এই চুক্তিটি ভেঙে পড়া এবং এটিকে পড়া-লেখার জন্য ডেরাইভেশনগুলির পক্ষে কোনও ধারণা নেই।

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

public class BarProvider
{ BaseClass _source;
  Bar _currentBar;

  public void setSource(BaseClass b)
  {
    _source = b;
    _currentBar = b.Bar;
  }

  public Bar getBar()
  { return _currentBar;  }
}

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

আপডেট : ইলিয়া রাইঝেঙ্কভ জিজ্ঞাসা করেছেন 'তখন কেন একই নিয়ম অনুসারে ইন্টারফেসগুলি খেলা হয় না?' হুম .. এইটা ভাবতে ভাবতে ভাবতে ভাব খারাপ হয়ে যায়।
একটি ইন্টারফেস হ'ল একটি চুক্তি যা বলে যে 'বার নামে একটি পঠিত সম্পত্তি থাকার একটি বাস্তবায়ন আশা করি।' ব্যক্তিগতভাবে আমি যদি কেবল কোনও ইন্টারফেস দেখি তবে কেবল পঠনযোগ্য এই ধারণাটি তৈরি করার সম্ভাবনা আমার খুব কম। আমি যখন কোনও ইন্টারফেসে কেবল-প্রাপ্ত-সম্পত্তি দেখি, তখন আমি এটি পড়ি 'কোনও প্রয়োগকরণ এই বৈশিষ্ট্য বারটি প্রকাশ করবে "... বেস-ক্লাসে এটি ক্লিক করে' বারটি কেবল পঠনযোগ্য সম্পত্তি '। অবশ্যই প্রযুক্তিগতভাবে আপনি চুক্তিটি ভঙ্গ করছেন না .. আপনি আরও করছেন। সুতরাং আপনি এক অর্থে সত্যই বলেছেন .. 'ভুল বোঝাবুঝির পক্ষে এটি যথাসম্ভব কঠোর করা' বলে আমি বন্ধ করে দিয়েছি।


94
আমি এখনও বিশ্বাস করি না। এমনকি যদি কোনও সুস্পষ্ট সেটেটর না থাকে তবে এটি গ্যারান্টি দেয় না যে সম্পত্তি সর্বদা একই বস্তুটি ফিরিয়ে দেবে - এটি অন্য কোনও পদ্ধতিতে এখনও পরিবর্তন করা যেতে পারে।
ripper234

34
ইন্টারফেসের ক্ষেত্রেও কি একই হওয়া উচিত নয়? আপনার ইন্টারফেসে কেবল পাঠযোগ্য সম্পত্তি থাকতে পারে এবং প্রয়োগের ধরণে পড়তে / লিখতে পারেন।
ইলিয়া রাইজেনকভ

49
আমি একমত নই: বেস ক্লাসটি কেবল সম্পত্তি স্থির করে না বলে ঘোষণা করে; সম্পত্তি কেবল পঠনযোগ্য হিসাবে এটি একই নয়। "কেবল পঠনযোগ্য" কেবলমাত্র এটির অর্থ যা আপনি এটি অর্পণ করেছেন। সি # তে মোটেও কোনও প্রাসঙ্গিক গ্যারান্টি নেই। আপনার পেতে পারে এমন একমাত্র সম্পত্তি যা প্রতিবার পরিবর্তিত হয়, বা একটি সেট / সেট সম্পত্তি যেখানে সেটার একটি নিক্ষেপ করে InvalidOperationException("This instance is read-only")
রোমান স্টারকভ 13

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

37
-1 আমি এই উত্তরটির সাথে একমত নই এবং এটি বিভ্রান্তিকর বলে মনে করি। যেহেতু একটি বেস ক্লাস আচরণটি সংজ্ঞায়িত করে যে কোনও শ্রেণীর অবশ্যই মেনে চলতে হবে (লিসকভের সাবস্টিটিউশন নীতিটি দেখুন), তবে আচরণ যুক্ত করার ক্ষেত্রে (এবং না হওয়া উচিত) সীমাবদ্ধ করে না। একটি বেস শ্রেণি কেবল আচরণটি কী হতে হবে তা সংজ্ঞায়িত করতে পারে এবং আচরণটি 'কী হবে না' (অর্থাত্ কংক্রিটের স্তরে লেখার যোগ্য হওয়া উচিত নয়) নির্দিষ্ট করতে পারে না (এবং হওয়া উচিত নয়)।
মার্সেল ভালদেজ ওরোজকো

39

আমি মনে করি মূল কারণটি হ'ল সিন্টেক্সটি অন্য কোনও উপায়ে কাজ করার জন্য এটি খুব স্পষ্ট। এই কোড:

public override int MyProperty { get { ... } set { ... } }

একেবারে স্পষ্ট যে উভয় getএবং উভয়ই setওভাররাইড হয়। setবেস ক্লাসে কোনও নেই , তাই সংকলকটি অভিযোগ করে। বেস ক্লাসে সংজ্ঞায়িত নয় এমন কোনও পদ্ধতি আপনি যেমন ওভাররাইড করতে পারবেন না তেমন আপনি কোনও সেটারকেও ওভাররাইড করতে পারবেন না।

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

আমি মনে করি নীচের বাক্য গঠনটি দুর্দান্তভাবে করতে পারে তবে এরিক লিপার্ট যেমন বলে চলেছে যে এর মতো একটি ছোটখাটো বৈশিষ্ট্য প্রয়োগ করা এখনও প্রচুর পরিমাণে প্রচেষ্টা ...

public int MyProperty
{
    override get { ... }
    set { ... }
}

বা, স্বয়ংক্রিয়রূপিত বৈশিষ্ট্যগুলির জন্য,

public int MyProperty { override get; set; }

19

আমি আজ খুব একই সমস্যা জুড়ে হোঁচট খেয়েছি এবং আমি মনে করি এটি পাওয়ার জন্য এর একটি খুব বৈধ কারণ রয়েছে।

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

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

interface ITest
{
    // Other stuff
    string Prop { get; }
}

// Implements other stuff
abstract class ATest : ITest
{
    abstract public string Prop { get; }
}

// This implementation of ITest needs the user to set the value of Prop
class BTest : ATest
{
    string foo = "BTest";
    public override string Prop
    {
        get { return foo; }
        set { foo = value; } // Not allowed. 'BTest.Prop.set': cannot override because 'ATest.Prop' does not have an overridable set accessor
    }
}

// This implementation of ITest generates the value for Prop itself
class CTest : ATest
{
    string foo = "CTest";
    public override string Prop
    {
        get { return foo; }
        // set; // Not needed
    }
}

আমি জানি এটি কেবল একটি "আমার 2 সেন্ট" পোস্ট, তবে আমি মূল পোস্টারটি দিয়ে অনুভব করি এবং এটি যুক্তিযুক্ত করার চেষ্টা করছি যে এটি আমার পক্ষে একটি ভাল বিষয়, বিশেষত বিবেচনা করে যে সরাসরি কোনও উত্তরাধিকার সূত্রে প্রাপ্ত হওয়ার সময় একই সীমাবদ্ধতাগুলি প্রয়োগ হয় না ইন্টারফেস.

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


2
বা, আমার ক্ষেত্রে, {পেতে; ব্যক্তিগত সেট; }। সেটটি ব্যক্তিগত থাকায় আমি কোনও চুক্তি লঙ্ঘন করছি না এবং এটি কেবল ডেরাইভেটিভ শ্রেণীর সাথে সম্পর্কিত।
ম্যাচটিন

16

এটা সম্ভব

tl; dr - আপনি চাইলে একটি গেট-ওয়ান পদ্ধতিতে একটি সেটার দিয়ে ওভাররাইড করতে পারেন। এটি মূলত:

  1. একটি newসম্পত্তি তৈরি করুন যা একই নাম ব্যবহার করে একটি getএবং একটি উভয়ই রয়েছে set

  2. আপনি যদি অন্য কিছু না করেন তবে getডেরিভেটিড ক্লাসটি যখন তার বেস টাইপের মাধ্যমে ডাকা হয় তখনও পুরানো পদ্ধতিটি ডাকা হবে। এটি ঠিক করার জন্য, একটি abstractমধ্যবর্তী স্তর যুক্ত overrideকরুন যা পুরাতন getপদ্ধতিতে এটি ব্যবহার করে নতুন getপদ্ধতির ফলাফল ফিরিয়ে দিতে বাধ্য করে ।

এটি আমাদের সাথে তার বৈশিষ্ট্যগুলির একটিরও অভাব থাকলেও get/ সহ বৈশিষ্ট্যগুলিকে ওভাররাইড করতে সক্ষম করে set

বোনাস হিসাবে, আপনি চাইলে রিটার্নের ধরণও পরিবর্তন করতে পারেন।

  • যদি বেস সংজ্ঞাটি কেবলমাত্র হয় getতবে আপনি আরও উত্পন্ন রিটার্ন টাইপ ব্যবহার করতে পারেন।

  • যদি বেস সংজ্ঞাটি কেবলমাত্র ছিল set, তবে আপনি আমাদের থেকে একটি স্বল্প-উত্পন্ন রিটার্ন টাইপ করতে পারেন।

  • যদি বেস সংজ্ঞাটি ইতিমধ্যে get/ ছিল set, তবে:

    • আপনি যদি এটি setকেবলমাত্র তৈরি করেন তবে আপনি আরও উদ্ভূত রিটার্ন টাইপ ব্যবহার করতে পারেন ;

    • আপনি যদি এটি getকেবলমাত্র তৈরি করেন তবে আপনি স্বল্প-উত্পন্ন রিটার্ন টাইপ ব্যবহার করতে পারেন ।

সব ক্ষেত্রে, আপনি চাইলে একই রিটার্নের ধরণটি রাখতে পারেন। নীচের উদাহরণগুলি সরলতার জন্য একই রিটার্ন টাইপ ব্যবহার করে।

পরিস্থিতি: প্রাক-বিদ্যমান- 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সম্পত্তি দিয়ে না পারলে আপনি এটি করতে পারেন :

  1. একই নামের সাথে একটি new get/ setসম্পত্তি তৈরি করুন ।

  2. 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একমাত্র বৈশিষ্ট্যে পদ্ধতি যুক্ত করতে দেয় । আপনি এটি স্টাফ করতে এটি ব্যবহার করতে পারেন:

  1. একটি মধ্যে কোনো সম্পত্তি পরিবর্তন get-only, set-only, অথবা get-and- setসম্পত্তি, এটা কি একটি বেস ক্লাসে ছিল নির্বিশেষে।

  2. উত্পন্ন ক্লাসে কোনও পদ্ধতির রিটার্নের ধরণ পরিবর্তন করুন।

প্রধান ত্রুটিগুলি হ'ল abstract classউত্তরাধিকার গাছটিতে আরও কোডিং এবং অতিরিক্ত রয়েছে। এটি নির্মাণকারীদের সাথে কিছুটা বিরক্তিকর হতে পারে যা পরামিতিগুলি নেয় কারণ তাদের মধ্যবর্তী স্তরটিতে অনুলিপি / আটকানো হয়।


এটি একটি নিজস্ব প্রশ্ন দিয়েছে: stackoverflow.com/questions/22210971
নাট

চমৎকার পন্থা (+1)। যদিও এটি সত্তা কাঠামোর সাথে সুষ্ঠুভাবে কাজ করবে কিনা তা আমি সন্দেহ করি।
মাইক ডি ক্লার্ক

9

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

আমার সন্দেহ হয় মাইক্রোসফ্টের এই সীমাবদ্ধতা হয় কারণ একই ভুল ধারণাটি প্রচারিত হয়েছিল, বা সম্ভবত ব্যাকরণকে সহজ করার কারণে; তবে, এখন সেই সুযোগটি স্বতন্ত্রভাবে পেতে বা সেট করার জন্য প্রয়োগ করা যেতে পারে, সম্ভবত আমরা আশা করতে পারি যে ওভাররাইডটিও খুব বেশি হতে পারে।

শীর্ষ ভোটের উত্তরের দ্বারা নির্দেশিত ভুল ধারণাটি, যে কেবল পঠনযোগ্য সম্পত্তি পড়ার / লেখার সম্পত্তির চেয়ে কোনওরকম "খাঁটি" হওয়া উচিত হাস্যকর। কাঠামোর মধ্যে কেবলমাত্র সাধারণ পঠনযোগ্য বৈশিষ্ট্যগুলি দেখুন; মান স্থির / নিখুঁতভাবে কার্যকর নয়; উদাহরণস্বরূপ, ডেটটাইম.এখন কেবল পঠনযোগ্য, তবে খাঁটি কার্যক্ষম মান ব্যতীত অন্য কিছু anything পরের বারের মতো একই মান ফিরে আসবে বলে ধরে নেওয়া কেবল একটি পঠিত সম্পত্তির মানকে 'ক্যাশে' করার প্রচেষ্টা ঝুঁকিপূর্ণ।

যাই হোক না কেন, এই সীমাবদ্ধতা কাটিয়ে উঠতে আমি নিম্নলিখিত কৌশলগুলির মধ্যে একটি ব্যবহার করেছি; উভয়ই নিখুঁত থেকে কম, তবে আপনাকে এই ভাষার ঘাটতি থেকে দূরে থাকতে দেবেন:

   class BaseType
   {
      public virtual T LastRequest { get {...} }
   }

   class DerivedTypeStrategy1
   {
      /// get or set the value returned by the LastRequest property.
      public bool T LastRequestValue { get; set; }

      public override T LastRequest { get { return LastRequestValue; } }
   }

   class DerivedTypeStrategy2
   {
      /// set the value returned by the LastRequest property.
      public bool SetLastRequest( T value ) { this._x = value; }

      public override T LastRequest { get { return _x; } }

      private bool _x;
   }

ডেটটাইম.নাউ নিখুঁতভাবে কার্যকরী, এতে কোনও পার্শ্ব-প্রতিক্রিয়া নেই (বাস্তবায়নে সময় লাগতে পারে এমনটি সম্ভবত একটি পার্শ্ব-প্রতিক্রিয়া বলা যেতে পারে, তবে মৃত্যুদন্ড কার্যকর হওয়ার সময় - কমপক্ষে যখন আবদ্ধ এবং সংক্ষিপ্ত - বিবেচনা করা হয় না) অন্য কোনও পদ্ধতির পার্শ্ব-প্রতিক্রিয়া, আমি এটিকে এখানেও এক হিসাবে বিবেচনা করব না)।
সুপারক্যাট

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

আপনি সঠিক যে আমার পরিভাষা অপ্রচলিত ছিল, তবে আমি মনে করি যে কোনও কিছুর কোনও পদ্ধতির পরিবর্তে কেবল পঠনযোগ্য সম্পত্তি হওয়ার যথাযথতা বিশুদ্ধতার চেয়ে পার্শ্ব-প্রতিক্রিয়াগুলির অভাবের উপর নির্ভরশীল।
সুপারক্যাট

2

আপনি একটি নতুন সম্পত্তি তৈরি করে সম্ভবত সমস্যাটি ঘুরে দেখতে পারেন:

public new int Bar 
{            
    get { return 0; }
    set {}        
}

int IBase.Bar { 
  get { return Bar; }
}

4
তবে আপনি কেবল এটি কোনও ইন্টারফেস প্রয়োগ করার সময় করতে পারেন, বেস ক্লাস থেকে উত্তরাধিকার সূত্রে নয়। আপনাকে অন্য একটি নাম বেছে নিতে হবে।
সোভিক

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

1

আমি আপনার সমস্ত পয়েন্ট বুঝতে পারি, তবে কার্যকরভাবে, সি # 3.0 এর স্বয়ংক্রিয় বৈশিষ্ট্যগুলি সে ক্ষেত্রে অকেজো হয়ে যায়।

আপনি এর মতো কিছু করতে পারবেন না:

public class ConcreteClass : BaseClass
{
    public override int Bar
    {
        get;
        private set;
    }
}

আইএমও, সি # এরকম পরিস্থিতিতে সীমাবদ্ধ করা উচিত নয়। এটি সেই অনুযায়ী ব্যবহার করা বিকাশের দায়িত্ব।


আমি আপনার বক্তব্য বুঝতে পারি না। আপনি কি সম্মতি দেন যে সি # এর দ্বারা একটি সেটার যুক্ত করার অনুমতি দেওয়া উচিত, বা আপনি এই প্রশ্নের উত্তর দিয়েছিলেন এমন বেশিরভাগ লোকের সাথে আছেন?
ripper234

2
যেমনটি আমি বলেছি, আইএমও, সি # এর একটি সেটার যুক্ত করার অনুমতি দেওয়া উচিত। এটি সেই অনুযায়ী ব্যবহার করা বিকাশের দায়িত্ব।
থমাস ড্যানেকার

1

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

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


0

প্রতিবিম্বটি ব্যবহার করে এটি অর্জনের জন্য এখানে একটি কাজের আশেপাশে রয়েছে:

var UpdatedGiftItem = // object value to update;

foreach (var proInfo in UpdatedGiftItem.GetType().GetProperties())
{
    var updatedValue = proInfo.GetValue(UpdatedGiftItem, null);
    var targetpropInfo = this.GiftItem.GetType().GetProperty(proInfo.Name);
    targetpropInfo.SetValue(this.GiftItem, updatedValue,null);
}

এইভাবে আমরা কেবলমাত্র পঠনযোগ্য কোনও সম্পত্তিতে অবজেক্টের মান সেট করতে পারি। সমস্ত পরিস্থিতিতে যদিও কাজ নাও করতে পারে!


1
আপনি কি নিশ্চিত যে আপনি কোনও সেটারকে প্রতিবিম্বের মাধ্যমে কল করতে পারবেন যা অস্তিত্বহীন (যেমন বর্ণিত গেটর-কেবল বৈশিষ্ট্যগুলিতে ঘটে)?
বা ম্যাপার

0

আপনার প্রশ্নের শিরোনামটি এমন একটি বিবরণে পরিবর্তন করতে হবে যে আপনার প্রশ্নটি কেবল একটি বিমূর্ত সম্পত্তিকে ওভাররাইড করার ক্ষেত্রে, বা আপনার প্রশ্নটি সাধারণত কোনও শ্রেণীর প্রাপ্ত-কেবল সম্পত্তিটিকে ওভাররাইড করার ক্ষেত্রে।


যদি প্রাক্তন (একটি বিমূর্ত সম্পত্তি ওভাররাইডিং)

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

public int GetBar(){}

তবে যদি এর উপর আপনার কোনও নিয়ন্ত্রণ না থাকে এবং বেস শ্রেণীর কার্যকারিতা তার নিজস্ব পাবলিক সম্পত্তি (অদ্ভুত) থেকে পড়ে, তবে কেবল এটি করুন:

public abstract class BaseClass
{
    public abstract int Bar { get; }
}

public class ConcreteClass : BaseClass
{
    private int _bar;
    public override int Bar
    {
        get { return _bar; }
    }
    public void SetBar(int value)
    {
        _bar = value;
    }
}

আমি (অদ্ভুত) মন্তব্যটি উল্লেখ করতে চাই: আমি বলব সর্বোত্তম অনুশীলন হ'ল কোনও শ্রেণীর নিজস্ব পাবলিক বৈশিষ্ট্যগুলি ব্যবহার না করা, তবে তার ব্যক্তিগত / সুরক্ষিত ক্ষেত্রগুলি বিদ্যমান থাকলে সেগুলি ব্যবহার করা। সুতরাং এটি একটি ভাল প্যাটার্ন:

public abstract class BaseClass {
    protected int _bar;
    public int Bar { get { return _bar; } }
    protected void DoBaseStuff()
    {
        SetBar();
        //Do something with _bar;
    }
    protected abstract void SetBar();
}

public class ConcreteClass : BaseClass {
    protected override void SetBar() { _bar = 5; }
}

যদি দ্বিতীয়টি হয় (কোনও শ্রেণীর প্রাপ্ত-কেবলমাত্র সম্পত্তিটিকে ওভাররাইড করে)

প্রতিটি নন-অ্যাবস্ট্রাক্ট সম্পত্তির একটি সেটর থাকে। অন্যথায় এটি অকেজো এবং আপনার এটি ব্যবহার করা উচিত নয়। মাইক্রোসফ্ট আপনাকে যা করতে চায় তা করার অনুমতি দেয় না। কারণ হওয়ার কারণ: সেটারটি কোনও না কোনও রূপে বিদ্যমান এবং আপনি যা চান ভেরি সহজেই তা সম্পাদন করতে পারেন।

বেস ক্লাস, বা যে কোনও শ্রেণীর যেখানে আপনি একটি সম্পত্তি পড়তে পারেন {get;}, সেই সম্পত্তির জন্য কিছু ধরণের উন্মুক্ত সেটার রয়েছে। মেটাডেটা দেখতে এই রকম হবে:

public abstract class BaseClass
{
    public int Bar { get; }
}

তবে বাস্তবায়নের জটিলতার বর্ণালীটির দুটি প্রান্ত থাকবে:

কমপক্ষে কমপ্লেক্স:

public abstract class BaseClass
{
    private int _bar;
    public int Bar { 
        get{
            return _bar;
        }}
    public void SetBar(int value) { _bar = value; }
}

সর্বাধিক জটিল:

public abstract class BaseClass
{
    private int _foo;
    private int _baz;
    private int _wtf;
    private int _kthx;
    private int _lawl;

    public int Bar
    {
        get { return _foo * _baz + _kthx; }
    }
    public bool TryDoSomethingBaz(MyEnum whatever, int input)
    {
        switch (whatever)
        {
            case MyEnum.lol:
                _baz = _lawl + input;
                return true;
            case MyEnum.wtf:
                _baz = _wtf * input;
                break;
        }
        return false;
    }
    public void TryBlowThingsUp(DateTime when)
    {
        //Some Crazy Madeup Code
        _kthx = DaysSinceEaster(when);
    }
    public int DaysSinceEaster(DateTime when)
    {
        return 2; //<-- calculations
    }
}
public enum MyEnum
{
    lol,
    wtf,
}

আমার বক্তব্যটি, যেভাবেই হোক না কেন, আপনার কাছে সেটারটি উন্মুক্ত। আপনার ক্ষেত্রে, আপনি ওভাররাইড করতে পারেন int Barকারণ আপনি বেস ক্লাসটি এটি পরিচালনা করতে চান না, এটি কীভাবে পরিচালনা করছে তা পর্যালোচনা করার অ্যাক্সেস নেই বা আপনার ইচ্ছার বিরুদ্ধে কিছু কোড রিয়েল চটজলদি না দেওয়া হয়েছে ।

ল্যাটার এবং প্রাক্তন উভয় (উপসংহার)

দীর্ঘ-সংক্ষিপ্ত সংক্ষিপ্ত: মাইক্রোসফ্টের পক্ষে কোনও কিছু পরিবর্তন করা জরুরি নয়। আপনার প্রয়োগকারী শ্রেণি কীভাবে সেট আপ করা যায় এবং নির্মাতাকে স্যান করে, বেস ক্লাসের সমস্ত বা কোনওটিই ব্যবহার না করে আপনি চয়ন করতে পারেন।


0

ব্যবহারের ক্ষেত্রে কেবলমাত্র একটি ক্ষুদ্র উপসেটের জন্য সমাধান, তবে তবুও: সি # 6.0 এ "পঠনযোগ্য" সেটার স্বয়ংক্রিয়ভাবে ওভাররাইড গেটর বৈশিষ্ট্যগুলির জন্য যুক্ত হয়।

public abstract class BaseClass
{
    public abstract int Bar { get; }
}

public class ConcreteClass : BaseClass
{
    public override int Bar { get; }

    public ConcreteClass(int bar)
    {
        Bar = bar;
    }
}

-1

কারণ এটি এনক্যাপসুলেশন এবং বাস্তবায়ন গোপনের ধারণাটি ভেঙে দেবে। আপনি যখন কোনও শ্রেণি তৈরি করবেন, শিপ করবেন এবং তারপরে আপনার শ্রেণীর গ্রাহক নিজেকে এমন কোনও সম্পত্তি সেট করতে সক্ষম করে তোলে যার জন্য আপনি মূলত কেবল একজন প্রাপ্তি সরবরাহ করেন। এটি কার্যকরভাবে আপনার শ্রেণীর যে কোনও আক্রমণকারীকে বিঘ্নিত করবে যা আপনি আপনার প্রয়োগের উপর নির্ভর করতে পারেন।


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

পুনঃটুইট তবে এই পোস্টের প্রশ্নটি হল; আপনাকে কোনও চুক্তি না করে এমন বিমূর্তিতে কেন একটি সেটার যুক্ত করতে পারে না। আপনার মন্তব্য বিপরীত প্রশ্নে উপযুক্ত হবে; যদি বংশজাতের তার ব্যক্তিগত ক্ষেত্রের পুরোপুরি নিয়ন্ত্রণ থাকে তবে মাইক্রোসফ্ট কেন আপনাকে বিমূর্ততায় একটি পঠনযোগ্য সম্পত্তি তৈরি করার অনুমতি দেয়?
সুমেরে

+1: এই প্রশ্নটি কেন মাইক্রোসফ্ট আপনাকে চুক্তি ভঙ্গ করতে দেয় না about যদিও আপনার ডাউনভোটগুলির কারণ মাইক্রোসফ্ট কেন কেবল একটি চুক্তিকে কেবল পঠনযোগ্য সম্পত্তি অন্তর্ভুক্ত করার অনুমতি দেয় সে সম্পর্কে আরও বেশি কারণ। সুতরাং এই উত্তরটি প্রসঙ্গে সঠিক।
সুমেরে

@ সুমের চুক্তিতে উল্লেখ করা হয়নি যে সম্পত্তিটি পরিবর্তন করা যাবে না। এটি যা উল্লেখ করে তা হ'ল এমন একটি সম্পত্তি রয়েছে যা পড়তে পারে। একটি সেটার যুক্ত করা এই চুক্তিটি ভঙ্গ করবে না। আপনি কেবলমাত্র পঠনযোগ্য সম্পত্তি তৈরি করার অভিপ্রায় হিসাবে এটি ব্যাখ্যা করতে পারেন, তবে আপনি সি # 6 এ গ্যারান্টি দিতে পারবেন না যে এটি পরিবর্তন করার কোনও উপায় নেই, সুতরাং যে চুক্তির কথা আপনি ভাবছেন তা বাস্তবে নেই। একটি ইন্টারফেসের কথা চিন্তা করুন: এটি একটি গেটেবল (কেবলমাত্র না!) সম্পত্তিতে চুক্তি সরবরাহ করতে পারে। এই ইন্টারফেসটি একটি get + সেট সম্পত্তি ঠিক সূক্ষ্ম দ্বারা প্রয়োগ করা যেতে পারে।
রোমান স্টারকভ

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

-1

এটি অসম্ভব নয়। আপনাকে কেবল আপনার সম্পত্তিতে "নতুন" কীওয়ার্ডটি ব্যবহার করতে হবে। উদাহরণ স্বরূপ,

namespace {
    public class Base {
        private int _baseProperty = 0;

        public virtual int BaseProperty {
            get {
                return _baseProperty;
            }
        }

    }

    public class Test : Base {
        private int _testBaseProperty = 5;

        public new int BaseProperty {
            get {
                return _testBaseProperty;
            }
            set {
                _testBaseProperty = value;
            }
        }
    }
}

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

আশাকরি এটা সাহায্য করবে


29
এই উত্তরটি ভুল কারণ চিহ্নিত সম্পত্তিটি newআর ভার্চুয়াল বেস একটিকে ওভাররাইড করে না। বিশেষত, যদি বেস সম্পত্তিটি বিমূর্ত হয় , যেমন এটি মূল পোস্টে রয়েছে তবে মূল newশব্দটি একটি অ-বিমূর্ত সাবক্লাসে ব্যবহার করা অসম্ভব কারণ আপনাকে সমস্ত বিমূর্ত সদস্যকে ওভাররাইড করতে হবে।
টিমভি

এটি উদ্বেগজনকভাবে বিপজ্জনক কারণ একই জিনিস থাকা সত্ত্বেও নিম্নলিখিতগুলি বিভিন্ন ফলাফল Test t = new Test(); Base b = t; Console.WriteLine(t.BaseProperty)দেয় : আপনাকে 5 Console.WriteLine(b.BaseProperty)দেয়, আপনাকে 0 দেয় এবং যখন আপনার উত্তরসূরি এটিকে ডিবাগ করতে হয় আপনি আরও দূরে সরে যেতে চাইতেন।
মার্ক সোউল ২

আমি ডাব্লু / মার্ক সম্মত, এটি অত্যন্ত বাজে। যদি উভয় বেসপ্রপার্টি বাস্তবায়ন একই ভেরিয়েবল দ্বারা সমর্থিত হয় তবে আইএমএইচও যদিও ঠিক আছে। IE: _baseProperty সুরক্ষিত করুন এবং _ টেষ্টবেসপ্রপার্টি বাতিল করুন। এছাড়াও, এএফআইকে বেসটিতে বাস্তবায়ন ভার্চুয়াল হওয়ার দরকার নেই কারণ আপনি এটি আসলেই ওভাররাইড করছেন না।
বাষ্প

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

-1

বেস ক্লাসে কেবল পঠনযোগ্য বৈশিষ্ট্য নির্দেশ করে যে এই সম্পত্তি এমন একটি মান উপস্থাপন করে যা সর্বদা শ্রেণীর মধ্যে থেকে নির্ধারণ করা যায় (উদাহরণস্বরূপ কোনও বস্তুর (ডিবি-) প্রসঙ্গে মিলিত একটি এনাম মান)। সুতরাং মান নির্ধারণের দায়বদ্ধতা শ্রেণীর মধ্যেই থাকে।

একটি সেটার যুক্ত করা এখানে একটি বিশ্রী সমস্যার সৃষ্টি করবে: আপনি যদি ইতিমধ্যে একক সম্ভাব্য মান ব্যতীত অন্য কোনও কিছুতে মান সেট করে থাকেন তবে একটি বৈধতা ত্রুটি ঘটতে হবে।

যদিও নিয়মগুলি প্রায়শই ব্যতিক্রম হয়। এটি খুব ভালভাবে সম্ভব যে উদাহরণস্বরূপ একটি উত্সযুক্ত শ্রেণিতে প্রসঙ্গটি সম্ভাব্য এনাম মানগুলিকে 10 এর মধ্যে 3 পর্যন্ত সঙ্কুচিত করে, তবুও এই বস্তুর ব্যবহারকারীর এখনও কোনটি সঠিক তা সিদ্ধান্ত নেওয়া দরকার। উদ্ভূত শ্রেণীর এই অবজেক্টটির ব্যবহারকারীর কাছে মান নির্ধারণের দায়বদ্ধতার দায়িত্ব অর্পণ করা দরকার। উপলব্ধি করা গুরুত্বপূর্ণ যে এই বস্তুর ব্যবহারকারীর এই ব্যতিক্রম সম্পর্কে ভালভাবে সচেতন হওয়া উচিত এবং সঠিক মান নির্ধারণ করার জন্য দায়বদ্ধতা গ্রহণ করা উচিত

এই ধরণের পরিস্থিতিতে আমার সমাধানটি হ'ল সম্পত্তিটি কেবল পঠনযোগ্য রেখে যাওয়া এবং ব্যতিক্রমটিকে সমর্থন করার জন্য উত্পন্ন শ্রেণিতে একটি নতুন পঠন-লেখার সম্পত্তি যুক্ত করা। মূল সম্পত্তির ওভাররাইড সহজেই নতুন সম্পত্তির মান ফিরিয়ে দেবে। নতুন সম্পত্তিটিতে সঠিকভাবে এই ব্যতিক্রমের প্রসঙ্গটি সঠিকভাবে চিহ্নিত করতে পারে name

এটি গিশুর দ্বারা বৈধ মন্তব্যকেও সমর্থন করে: "ভুল বোঝাবুঝির পক্ষে এটি যথাসম্ভব কঠোর করুন" ish


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

একটি অতিরিক্ত সেটার ক্লাসের মধ্যে একটি প্রাইভেট ভেরিয়েবল পরিবর্তন করতে পারে। বেস শ্রেণীর তথাকথিত "কেবল পঠনযোগ্য" সম্পত্তি তারপরেও "শ্রেণীর মধ্যে থেকে" (নতুন বেসরকারী ভেরিয়েবলটি পড়ে) মান নির্ধারণ করে determine আমি বিষয়টি সেখানে দেখছি না। এছাড়াও দেখুন, উদাহরণস্বরূপ, কী List<T>.Countকরে: এটি নির্ধারিত হতে পারে না, তবে এর অর্থ এই নয় যে এটি "কেবল পঠনযোগ্য" যাতে এটি শ্রেণীর ব্যবহারকারীরা পরিবর্তন করতে পারে না। এটি তালিকা আইটেম যুক্ত করে এবং মুছে ফেলার মাধ্যমে অপ্রত্যক্ষভাবে খুব ভালভাবে সংশোধন করা যায়।
অথবা ম্যাপার

-2

কারণ আইএল স্তরে, একটি পঠন / লেখার সম্পত্তি দুটি (গেটর এবং সেটার) পদ্ধতিতে অনুবাদ করে।

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

সত্য, কোনও নতুন পদ্ধতি যুক্ত করা সামঞ্জস্যতা ভঙ্গ করবে না, তবে যেহেতু এটি গোপন থাকবে, তাই এটিকে অস্বীকার করার সিদ্ধান্তটি সঠিকভাবে বোঝায়।


2
আমি এখানে "বাইরের বিশ্বের" সম্পর্কে খুব বেশি চিন্তা করি না। আমি কোনও ক্লাসে কার্যকারিতা যুক্ত করতে চাই, যা সর্বদা কেবল কোডে প্রদর্শিত হয় যা নির্দিষ্ট শ্রেণিটি জানে এবং বেসটি নয়।
ripper234

@ রিপার 234 ম্যাট বল্টের উত্তর দেখুন: আপনি যদি নতুন সম্পত্তিটি কেবল উদ্ভূত শ্রেণীর ব্যবহারকারীদের কাছে দৃশ্যমান করতে চান তবে newপরিবর্তে আপনার ব্যবহার করা উচিত override
ড্যান বেরিনেডি

1
এটি লুকিয়ে থাকে না। আপনি বলার মতো যে আপনি শিশু-শ্রেণিতে একটি নতুন পদ্ধতি যুক্ত করতে পারবেন না কারণ নতুন পদ্ধতিটি "বাইরের বিশ্ব থেকে গোপন থাকবে"। অবশ্যই এটি বেস-ক্লাসের দৃষ্টিকোণ থেকে লুকানো রয়েছে, তবে এটি শিশু শ্রেণির ক্লায়েন্টদের কাছ থেকে অ্যাক্সেসযোগ্য। (অর্থাত্‍ কীভাবে প্রত্যাবর্তনকারীকে ফিরতে হবে তার প্রভাব ফেলতে হবে)
শিপি

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

-2

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


আপ-ভোট দিন। এটি খুব সংক্ষিপ্ত। মাইক্রোসফ্ট কেন বেস ক্লাসের গ্রাহককে চুক্তি ভঙ্গ করতে দেয়? আমি আমার দীর্ঘ-দীর্ঘ এবং বিভ্রান্তিমূলক উত্তরের এই খুব সংক্ষিপ্ত সংস্করণের সাথে একমত। হাঃ হাঃ হাঃ. আপনি যদি বেস ক্লাসের ভোক্তা হন তবে আপনার চুক্তিটি ভেঙে ফেলা উচিত নয়, তবে আপনি এটি কয়েকটি ভিন্ন উপায়ে প্রয়োগ করতে পারেন।
সুমেরে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.