কেবল গেটারের সাথে স্বয়ংক্রিয় সম্পত্তি, সেট করা যেতে পারে, কেন?


97

আমি একটি স্বয়ংক্রিয় সম্পত্তি তৈরি করেছি:

public int Foo { get; } 

এটি কেবল প্রাপ্তি। তবে আমি যখন কনস্ট্রাক্টর তৈরি করি তখন আমি মানটি পরিবর্তন করতে পারি:

public MyClass(string name)
{
    Foo = 5;
}

এটি কেবলমাত্র পাওয়ার পরেও কেন এটি সম্ভব?


এটি আসলে একটি সেটার ব্যবহার করে না (কারণ এটির একটি নেই)। এটি সরাসরি অন্তর্নিহিত ক্ষেত্রটি সেট করে (যা আমাদের কাছ থেকে লুকানো রয়েছে, এজন্য আপনাকে সম্পত্তিটির নামটি ব্যবহার করতে হবে)
ডেনিস_ ই

14
কোন সম্পত্তি কোন সম্পত্তি, যদি তা কখনই শুরু / সেট করা যায় না? ইয়াকুব মাসাদ এর সঠিক উত্তর দিয়েছেন
বিক্রম

উত্তর:


125

এটি এমএসডিএন ম্যাগাজিনের নিবন্ধ 'সি #: দ্য নিউ এবং উন্নত সি # 6.0' হিসাবে আলোচিত হিসাবে "গেটর-ওয়ানও-অ্যাটোর প্রোপার্টিস" হিসাবে পরিচিত, এটি একটি নতুন সি # 6 বৈশিষ্ট্য " মাইকেলিস এবং সি # 6.0 খসড়া ভাষায় নির্দিষ্টকরণ

কেবলমাত্র পঠনযোগ্য ক্ষেত্রের সেটারটি কেবল নির্মাত্রে অ্যাক্সেসযোগ্য, অন্যান্য সমস্ত পরিস্থিতিতে ক্ষেত্রটি এখনও কেবল পঠনযোগ্য এবং আগের মতো আচরণ করে।

আপনার টাইপ করতে হবে এমন কোডের পরিমাণ হ্রাস করার জন্য এবং মানটি ধরে রাখার জন্য একটি প্রাইভেট মডিউল স্তরের ভেরিয়েবল স্পষ্টভাবে ঘোষণা করার প্রয়োজনীয়তা অপসারণ করার জন্য এটি একটি সুবিধাযুক্ত বাক্য গঠন।

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

এই ব্লগ পোস্ট, '# 1,207 - সি # 6.0 - শন সেক্সটনের রচনা-পাঠযোগ্য সম্পত্তিগুলির জন্য অটো-প্রপার্টি ইনিশিয়ালাইজারগুলি' এর ভাল ব্যাখ্যা এবং উদাহরণ রয়েছে:

সি # .0.০ এর পূর্বে, আপনি যদি কেবল পঠনযোগ্য (অপরিবর্তনীয়) সম্পত্তি চান, তবে আপনি সাধারণত নীচে দেখানো হিসাবে কেবল কনস্ট্রাক্টরটিতে আরম্ভ হওয়া একটি পঠনযোগ্য ব্যাকিং ফিল্ড ব্যবহার করতে চান।

public class Dog 
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    private readonly DateTime creTime;
    public DateTime DogCreationTime 
    {
        get { return creTime; }
    }

    public Dog(string name)
    {
        Name = name;
        creTime = DateTime.Now;
    }
}

সি # 6.0 এ, আপনি কেবলমাত্র পঠনযোগ্য সম্পত্তি প্রয়োগ করতে স্ব-বাস্তবায়িত বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন। আপনি একটি অটো-প্রপার্টি আরম্ভকারী ব্যবহার করে এটি করেন। ফলাফলটি উপরের উদাহরণের তুলনায় অনেক পরিষ্কার, যেখানে আমাদের স্পষ্টভাবে একটি ব্যাকিং ফিল্ড ঘোষণা করতে হয়েছিল।

public class Dog
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    public DateTime DogCreationTime { get; } = DateTime.Now;

    public Dog(string name)
    {
        Name = name;
    }
}

গিটহাবের ডটনেট রোজলিন রেপোতে আরও বিশদ পাওয়া যাবে :

অটো-প্রোপার্টি এখন সেটর ছাড়াই ঘোষণা করা যেতে পারে।

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

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

এবং সি # 6.0 খসড়া ভাষায় স্পেসিফিকেশন (এনবি: মাইক্রোসফ্ট সম্পর্কিত হিসাবে ভাষা স্পেসিফিকেশন চূড়ান্ত, তবে এটি এখনও EMCA / ISO স্ট্যান্ডার্ড হিসাবে অনুমোদিত হয়নি , সুতরাং 'খসড়া'):

স্বয়ংক্রিয়ভাবে প্রয়োগ করা বৈশিষ্ট্য

একটি স্বয়ংক্রিয়ভাবে প্রয়োগ করা সম্পত্তি (বা সংক্ষেপে স্ব-সম্পত্তি), সেমিকোলন-কেবলমাত্র অ্যাকসেসর বডিসহ একটি অ-বিমূর্ত অ-বহিরাগত সম্পত্তি। অটো-প্রোপার্টিগুলির অবশ্যই একটি গেট অ্যাকসেসর থাকতে হবে এবং optionচ্ছিকভাবে একটি সেট অ্যাক্সেসর থাকতে পারে।

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

একটি স্ব-সম্পত্তিতে optionচ্ছিকভাবে সম্পত্তি_initializer থাকতে পারে, যা ভেরিয়েবল_আইনিটিয়ালাইজার (ভেরিয়েবল আরম্ভকারী) হিসাবে সরাসরি ব্যাকিং ফিল্ডে প্রয়োগ করা হয়।


4
এটি বোকা নকশা। সম্পত্তিটি কেবল পঠনযোগ্য হিসাবে বিবেচিত এমন কোনও স্থানে সেট করা থাকলে এটি একটি সংকলন সময় ত্রুটি হওয়া উচিত।
শিব

আমার কাছে অদ্ভুততা হ'ল CS0200 C# Property or indexer cannot be assigned to -- it is read onlyনিয়মিত সম্পত্তি ব্যবহার করার সময় এখনও একটি সংকলক ত্রুটি আছে । "গেটর-অটো-প্রোপার্টি" কেবল পঠনযোগ্য হিসাবে বিবেচনা করা হয় বা না?
কাইল ডেলাানি

25

এটি সি # 6 এ একটি নতুন বৈশিষ্ট্য যা আপনাকে কেবল পঠনযোগ্য বৈশিষ্ট্য তৈরি করতে এবং নির্মাণকারীর কাছ থেকে তাদের মানগুলি আরম্ভ করার অনুমতি দেয় (অথবা আপনি যখন তাদের ঘোষণা করেন তখন ইনলাইন)।

আপনি যদি নির্মাণকারীর বাইরে এই সম্পত্তিটির মান পরিবর্তন করার চেষ্টা করেন তবে এটি আপনাকে একটি সংকলন ত্রুটি দেয়।

এটি কেবলমাত্র সেই অর্থে পঠনযোগ্য যা একবার আপনি এর মানটি শুরু করেন (কনস্ট্রাক্টরের সাথে ইনলাইন বা ভিতরে) আপনি তার মান পরিবর্তন করতে পারবেন না।


তো, এর ব্যাখ্যা কী? প্রাপ্তির সংজ্ঞা কী?
নোম বি

16

যদি কনস্ট্রাক্টর (বা একটি স্বয়ং-সম্পত্তি প্রারম্ভিক) থেকে পঠনযোগ্য সম্পত্তিটি আরম্ভ করা সম্ভব না হয় তবে এটি অকেজো হবে, কারণ এটি সর্বদা তার ধরণের (সংখ্যার জন্য 0, রেফারেন্সের ধরণের জন্য নাল) ফেরত দেবে )। সমস্ত সি # সংস্করণে কেবল পঠনক্ষেত্রের ক্ষেত্রে একই শব্দার্থক প্রয়োগ হয়েছে ।

সত্যিকারের গেটর-কেবল সম্পত্তি সংজ্ঞায়িত করতে (এটি নির্মাণকারীর কাছ থেকে আরম্ভ করা যায় না), আপনাকে সংজ্ঞাটির অংশ হিসাবে এটি কী দেয় তা নির্দিষ্ট করতে হবে:

public int Foo { get { return 5; } }

অথবা, সি # 6 তে আরও সংক্ষিপ্তভাবে:

public int Foo => 5;

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

4
@ সেবাগোমেজ: আমি নিশ্চিত নই যে আমি আপনার বক্তব্য পাচ্ছি - আমার উদাহরণে আমি যা প্রদর্শন করেছি তা কি তা নয়?
ডগলাস

5

"পঠনযোগ্যভাবে স্বয়ংক্রিয়ভাবে প্রয়োগ করা সম্পত্তি"

সবার আগে আমি স্পষ্ট করতে চাই যে সম্পত্তিটি পছন্দ করে

public string FirstName { get; }

"কেবলমাত্র পঠনযোগ্য স্বয়ংক্রিয়ভাবে প্রয়োগকৃত বৈশিষ্ট্য" হিসাবে পরিচিত

এটি যাচাই করতে আপনি ভিজ্যুয়াল স্টুডিও সহ উপরের কোডটি চালাতে ও পরীক্ষা করতে পারেন। আপনি যদি ভাষা সংস্করণটি সি # 6.0 থেকে সি # 5.0 তে পরিবর্তন করেন তবে সংকলকটি নিম্নলিখিত ব্যতিক্রমগুলি ছুঁড়ে ফেলবে বৈশিষ্ট্য 'কেবলমাত্র পঠনযোগ্যভাবে প্রয়োগ করা বৈশিষ্ট্য' সি # 5 তে উপলভ্য নয় দয়া করে ভাষা সংস্করণ 6 বা তার বেশি ব্যবহার করুন।

সি # ভাষার সংস্করণ পরিবর্তন করতে এখানে যান

এখন আমি আপনার দ্বিতীয় প্রশ্ন আসছে

“এটি কেবল প্রাপ্তি। তবে আমি যখন কনস্ট্রাক্টর তৈরি করি তখন আমি মানটি পরিবর্তন করতে পারি "

মাইক্রোসফ্ট কেবল পঠনের যুক্তিতে "কেবলমাত্র পঠনযোগ্য স্বয়ংক্রিয়ভাবে প্রয়োগযোগ্য বৈশিষ্ট্যগুলি" উপস্থাপন করে। যেমনটি আমরা জানি যে "পাঠ্যপুস্তক" শব্দটি সি # 1.0 থেকে পাওয়া যায়। আমরা ব্যবহার করুন "কেবলমাত্র" একটি ক্ষেত্র উপর পরিবর্তক এবং যে ক্ষেত্র হিসেবে শব্দ নির্ধারিত করা যেতে পারে 2 উপায় পারেন ঘোষণার সময়ে বা একই শ্রেণীতে একটি কন্সট্রাকটর হবে।

একইভাবে "কেবলমাত্র পঠনযোগ্য স্বয়ংক্রিয়ভাবে প্রয়োগকৃত সম্পত্তি" এর মান 2 উপায়ে অর্পণ করা যেতে পারে

ওয়ে 1 (ঘোষণার সময়):

public string FirstName { get; } = "Banketeshvar";

ওয়ে 2 (একই বর্গের কনস্ট্রাক্টারে)

Person()
{
 FirstName  = "Banketeshvar";
}

খাঁটি পঠনযোগ্য সম্পত্তি

আপনি যদি খাঁটি মাত্র পঠনযোগ্য সম্পত্তি খুঁজছেন তবে এর জন্য যান

public string FullName => "Manish Sharma";

এখন আপনি কনস্ট্রাক্টর থেকে "ফুলনাম" প্রিউটির মান নির্ধারণ করতে পারবেন না। আপনি যদি এটির চেষ্টা করেন তবে এটি নিম্নলিখিত ব্যতিক্রমগুলি ছুঁড়ে দেবে

"সম্পত্তি বা সূচক 'ব্যক্তি' পূর্ণ নাম 'বরাদ্দ করা যায় না - এটি কেবল পঠিত হয়"


4
নোট করুন যে পুরো নাম => "ফু বার" প্রতিটি সময় মূল্যায়ন করা হবে।
juFo

4

সি # 3.0 প্রকাশের সময় ভাষাতে অটো সম্পত্তি বৈশিষ্ট্য যুক্ত করা হয়েছিল। এটি আপনাকে কোনও ব্যাকিং ফিল্ড ছাড়াই সম্পত্তি সংজ্ঞায়িত করতে দেয়, তবে আপনাকে অ-ডিফল্ট মানতে এই স্বয়ংক্রিয় বৈশিষ্ট্যগুলি আরম্ভ করার জন্য কনস্ট্রাক্টর ব্যবহার করতে হবে। সি # 6.0 অটো প্রপার্টি ইনিশিয়ালাইজার নামে একটি নতুন বৈশিষ্ট্য উপস্থাপন করেছে যা নীচের মতো নির্মাতাকে ছাড়াই আপনাকে এই বৈশিষ্ট্যগুলি আরম্ভ করতে দেয়:

পূর্বে, যদি আপনি কোনও অটো-প্রপার্টি ব্যবহার করে অবজেক্ট তৈরি করতে চান এবং নীচের মতো একটি অ-ডিফল্ট মানতে একটি অটো-সম্পত্তি শুরু করতে চান তবে কোনও কনস্ট্রাক্টর প্রয়োজন:

public class MyClass
{
    public int Foo { get; }

    public Foo(int foo)
    {
        Foo = foo;
    }
}

এখন সি # 6.0 এ, অটো-প্রপার্টি সহ একটি ইনিশিয়ালাইজার ব্যবহার করার ক্ষমতা মানে কোনও স্পষ্টত নির্মাণকারী কোডের প্রয়োজন হয় না।

public string Foo { get; } = "SomeString";

public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };

আপনি এখানে আরও তথ্য পেতে পারেন


1

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

পাঠ্য-লেখার অটো-বৈশিষ্ট্যগুলি যেমন সাধারণ ক্ষেত্রগুলির মতো সহজে ক্লাসগুলিকে পরিবর্তনযোগ্য বৈশিষ্ট্যগুলি প্রকাশ করতে দেয়, তেমনি পঠনযোগ্য অটো- readonlyগুণাবলীর উপস্থিতি শ্রেণিগুলিকে সহজেই যোগ্যতাযুক্ত ক্ষেত্রগুলির মতো অপরিবর্তনীয় বৈশিষ্ট্য প্রকাশ করতে দেয় । readonlyযোগ্যতাযুক্ত ক্ষেত্রগুলি যেমন কোনও কনস্ট্রাক্টরে লেখা যেতে পারে তেমনিভাবে কেবল-প্রাপ্ত বৈশিষ্ট্যগুলিও।

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