সি # 3.0+ এ সম্পত্তি এবং ক্ষেত্রের মধ্যে পার্থক্য


140

আমি বুঝতে পারি যে এটির একটি সদৃশ বলে মনে হচ্ছে কোনও ক্ষেত্র এবং সি # এর একটি সম্পত্তির মধ্যে পার্থক্য কী? তবে আমার প্রশ্নের কিছুটা পার্থক্য রয়েছে (আমার দৃষ্টিকোণ থেকে):

একবার আমি জানি যে

  • আমি আমার ক্লাসটি "কৌশলগুলির সাথে ব্যবহার করি না যা কেবলমাত্র বৈশিষ্ট্যগুলিতে কাজ করে" এবং
  • আমি গেটর / সেটারে বৈধতা কোড ব্যবহার করব না।

সম্পত্তি নির্ধারণের ক্ষেত্রে কোনও ধরণের নিয়ন্ত্রণের মতো (শৈলী / ভবিষ্যতের উন্নয়নগুলি বাদ দিয়ে) কি কোনও পার্থক্য রয়েছে?

এর মধ্যে কোনও অতিরিক্ত পার্থক্য রয়েছে:

public string MyString { get; set; }

এবং

public string myString;

(আমি সচেতন যে, প্রথম সংস্করণে সি # 3.0 বা তার বেশি এবং সংকলকটি ব্যক্তিগত ক্ষেত্রগুলি তৈরি করে requires


উত্তর:


117

Encapsulation।

দ্বিতীয় উদাহরণে আপনি সবেমাত্র একটি ভেরিয়েবল সংজ্ঞায়িত করেছেন, প্রথমটিতে ভেরিয়েবলের চারপাশে একটি গিটার / সেটার রয়েছে। সুতরাং আপনি যদি সিদ্ধান্ত নেন যে আপনি পরবর্তী তারিখে ভেরিয়েবলটি বৈধ করতে চান - এটি অনেক সহজ হবে।

এছাড়াও তারা ইন্টেলিসেন্সে আলাদাভাবে দেখায় :)

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


9
কেন সহজ হবে? ক্ষেত্রটি একটি সম্পত্তি হিসাবে পরিণত করতে এবং একটি বেসরকারী ব্যাকিং ফিল্ড যুক্ত করা থেকে আমাকে কী বাধা দেয়? এটি কীভাবে কলিং কোডকে প্রভাবিত করে?
সার্জ ওয়াটিয়ার

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

আমি আপনার সাথে পুরোপুরি একমত, আমি সর্বদা সম্পত্তি ব্যবহার করি। আমি সম্ভবত একটি সম্ভাব্য পার্থক্য সম্পর্কে কৌতূহল ছিলাম
p4bl0

24
যদি গ্রাহক কোডটি সর্বদা প্রভাবিত শ্রেণির একই সময়ে পুনরায় সংযুক্ত করা হয় (সুতরাং অভ্যন্তরীণ অভ্যন্তরীণ ব্যতীত ব্যক্তিগত বা অভ্যন্তরীণ যে কোনও কিছুই 100% নিরাপদ থাকে) তবে এটিকে ক্ষেত্র তৈরি করা পুরোপুরি ঠিক আছে
ShuggyCoUk

1
বাহ শুগি আপনার মন্তব্যটি ঠিক উত্তরটি আমি খুঁজছিলাম!
p4bl0

160

ক্ষেত্র এবং বৈশিষ্ট্যগুলি একই দেখায় তবে তা নয়। বৈশিষ্ট্যগুলি হল একটি পদ্ধতি এবং যেমন কিছু নির্দিষ্ট জিনিস রয়েছে যা সম্পত্তিগুলির জন্য সমর্থিত নয় এবং কিছু জিনিস যা বৈশিষ্ট্যের সাথে ঘটে তবে ক্ষেত্রগুলির ক্ষেত্রে কখনও হয় না।

পার্থক্যের একটি তালিকা এখানে:

  • ক্ষেত্রগুলি out/refআর্গুমেন্টের ইনপুট হিসাবে ব্যবহার করা যেতে পারে। সম্পত্তি পারে না।
  • একাধিকবার কল করা হলে একটি ক্ষেত্র সর্বদা একই ফলাফল দেয় (যদি আমরা একাধিক থ্রেড সহ সমস্যাগুলি ছেড়ে দিই)। যেমন একটি সম্পত্তি DateTime.Nowসবসময় নিজের সমান হয় না।
  • সম্পত্তিগুলি ব্যতিক্রম ছুঁড়ে ফেলতে পারে - ক্ষেত্রগুলি কখনই এটি করবে না।
  • বৈশিষ্ট্যের পার্শ্ব প্রতিক্রিয়া হতে পারে বা কার্যকর করতে সত্যই দীর্ঘ সময় নিতে পারে। ক্ষেত্রগুলির কোনও পার্শ্ব প্রতিক্রিয়া নেই এবং প্রদত্ত প্রকারের জন্য আশা করা যায় এমন সবসময় তত দ্রুত হবে।
  • সম্পত্তি গেটার্স / সেটারগুলির জন্য পৃথক অ্যাক্সেসিবিলিটি সমর্থন করে - ক্ষেত্রগুলি দেয় না (তবে ক্ষেত্রগুলি তৈরি করা যায় readonly)
  • প্রতিবিম্ব ব্যবহার করার সময় বৈশিষ্ট্য এবং ক্ষেত্রগুলি পৃথক হিসাবে বিবেচনা করা হয় MemberTypesযাতে তারা আলাদাভাবে অবস্থিত ( উদাহরণস্বরূপ GetFieldsবনাম GetProperties)
  • জেআইটি সংকলক ক্ষেত্রের অ্যাক্সেসের তুলনায় সম্পত্তি অ্যাক্সেসকে খুব আলাদাভাবে আচরণ করতে পারে। এটি তবে অভিন্ন নেটিভ কোডে সংকলন করতে পারে তবে পার্থক্যের সুযোগ রয়েছে।

11
তবে নোট করুন যে ভাল অভ্যাসগুলি নিযুক্ত করা হয় তবে এই পয়েন্টগুলির মধ্যে বেশিরভাগের মধ্যে পার্থক্য হওয়া উচিত নয় । অর্থাৎ, সম্পত্তিগুলির সত্যই কখনই পার্শ্ব প্রতিক্রিয়া হওয়া উচিত নয়, এগুলি কার্যকর করতে দীর্ঘ সময় নেওয়া উচিত নয়।
নলডোরিন

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

4
হ্যাঁ, যথেষ্ট ন্যায্য। শিক্ষানবিস প্রোগ্রামারদের দুর্ভাগ্যবশত বারংবার এসব সম্পর্কে একটি খেই না, ...
Noldorin

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

3
আমি মনে করি এই উত্তরটি গৃহীত উত্তরের চেয়ে বিশালত্ব better আমি ভাবতে শুরু করি যে সবসময় ক্ষেত্রের চেয়ে সম্পত্তি পছন্দ করার "গ্রহণযোগ্য" উপায়টি খারাপ চিন্তাভাবনা। আপনার যদি কেবল ডেটা নিয়ে ডিল করতে হয় তবে একটি ক্ষেত্র ব্যবহার করুন। যদি আপনাকে ডেটাতে কার্যকারিতা প্রয়োগ করতে হয় তবে একটি পদ্ধতি ব্যবহার করুন। যেহেতু বৈশিষ্ট্যগুলির পার্শ্ব-প্রতিক্রিয়া থাকতে পারে আপনি অবহিত নন (বিশেষত যদি আপনি গ্রন্থাগারটি ডিজাইন করেন নি এবং যদি খুব কম ডকুমেন্টেশন থাকে) তবে বেশিরভাগ ক্ষেত্রে এগুলি আমার কাছে স্বজ্ঞাত বলে মনে হয়।
ডেভিড পিটারসন

41

একটি দম্পতি দ্রুত, সুস্পষ্ট পার্থক্য

  1. একটি সম্পত্তি অ্যাক্সেসর কীওয়ার্ড থাকতে পারে।

    public string MyString { get; private set; }
  2. কোনও সম্পত্তি বংশধরদের মধ্যে ওভাররাইড করা যায়।

    public virtual string MyString { get; protected set; }

1
মিমিচ .. এনআর 2 আকর্ষণীয় .. আমি এটি নিয়ে ভাবি নি
p4bl0

14

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


11

ক্ষেত্রের চেয়ে অ্যাকসেসর বেশি। অন্যরা ইতিমধ্যে বেশ কয়েকটি গুরুত্বপূর্ণ পার্থক্য চিহ্নিত করেছে এবং আমি আরও একটি যুক্ত করতে যাচ্ছি।

বৈশিষ্ট্য ইন্টারফেস ক্লাসে অংশ নেয়। উদাহরণ স্বরূপ:

interface IPerson
{
    string FirstName { get; set; }
    string LastName { get; set; }
}

এই ইন্টারফেসটি বিভিন্ন উপায়ে সন্তুষ্ট হতে পারে। উদাহরণ স্বরূপ:

class Person: IPerson
{
    private string _name;
    public string FirstName
    {
        get
        {
            return _name ?? string.Empty;
        }
        set
        {
            if (value == null)
                throw new System.ArgumentNullException("value");
            _name = value;
        }
    }
    ...
}

এই বাস্তবায়নে আমরা উভয় Personশ্রেণিকে একটি অবৈধ অবস্থায় প্রবেশের হাত থেকে রক্ষা করছি , সেই সাথে কলারকে স্বাক্ষরিত সম্পত্তি থেকে বাতিল করা থেকে রক্ষা করব।

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

interface IPerson
{
    string FirstName { get; }
    string LastName { get; }
}

Personশ্রেণীর পূর্ববর্তী প্রয়োগ এই ইন্টারফেসটিকে সন্তুষ্ট করে। এটি যে কলারকেও বৈশিষ্ট্যগুলি সেট করতে দেয় তা ভোক্তাদের দৃষ্টিকোণ থেকে (যারা গ্রাস করে IPerson) অর্থহীন । কংক্রিট বাস্তবায়নের অতিরিক্ত কার্যকারিতা বিবেচনা করা হয়, উদাহরণস্বরূপ, নির্মাতা:

class PersonBuilder: IPersonBuilder
{
    IPerson BuildPerson(IContext context)
    {

        Person person = new Person();

        person.FirstName = context.GetFirstName();
        person.LastName = context.GetLastName();

        return person;

    }
}

...

void Consumer(IPersonBuilder builder, IContext context)
{
    IPerson person = builder.BuildPerson(context);
    Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}

এই কোডটিতে, ভোক্তা সম্পত্তি সেটটারগুলি সম্পর্কে জানেন না - এটি সম্পর্কে জানা তাঁর ব্যবসা নয়। গ্রাহককে কেবল গ্রাহক প্রয়োজন, এবং তিনি ইন্টারফেস থেকে অর্থাত্ চুক্তি থেকে গ্রাহক হন।

এর অপর একটি সম্পূর্ণ বৈধ বাস্তবায়ন IPersonহবে অপরিবর্তনীয় ব্যক্তি শ্রেণি এবং সংশ্লিষ্ট ব্যক্তির কারখানা:

class Person: IPerson
{
    public Person(string firstName, string lastName)
    {

        if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName))
            throw new System.ArgumentException();

        this.FirstName = firstName;
        this.LastName = lastName;

    }

    public string FirstName { get; private set; }

    public string LastName { get; private set; }

}

...

class PersonFactory: IPersonFactory
{
    public IPerson CreatePerson(string firstName, string lastName)
    {
        return new Person(firstName, lastName);
    }
}
...
void Consumer(IPersonFactory factory)
{
    IPerson person = factory.CreatePerson("John", "Doe");
    Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}

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


7

প্রথমটি:

public string MyString {get; set; }

একটি সম্পত্তি; দ্বিতীয়টি ( public string MyString) একটি ক্ষেত্রকে বোঝায়।

পার্থক্যটি হ'ল, সেই নির্দিষ্ট কৌশলগুলি (উদাহরণগুলির জন্য এএসপি.এনইটি ডাটাবেইন্ডিং) কেবলমাত্র বৈশিষ্ট্যগুলিতে কাজ করে, ক্ষেত্রগুলিতে নয়। এক্সএমএল সিরিয়ালাইজেশনের ক্ষেত্রেও এটি একই: কেবলমাত্র বৈশিষ্ট্যগুলি ক্রমিকায়িত হয়, ক্ষেত্রগুলি সিরিয়ালীকৃত হয় না।


8
ভুল। এক্সএমএল সিরিয়ালাইজেশন পাবলিক ফিল্ডগুলিকে সিরিয়ালাইজ করে।
সার্জ ওয়াটিয়ার

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

DRY করা ভাল;) তবে আমি আবারও লিখি, আমি সি # ভাষায় সম্পত্তির দৃ property় ভূমিকা পছন্দ করি। জাভা তুলনায় অনেক ভাল বাস্তবায়িত হয়েছে (ফলস্বরূপ শুরু থেকে) অনেকগুলি, সম্ভবত সমস্ত নেট নেটওয়াসই কেবল বৈশিষ্ট্যগুলিতে কাজ করে। ডাব্লুপিএফ, এএসপিএক্স এবং আরও অনেক কিছু।
জ্যাসেক সিজেট

3

সম্পত্তি এবং ক্ষেত্রগুলি অনেক ক্ষেত্রে একই রকম মনে হতে পারে তবে তা তা নয়। ক্ষেত্রগুলির জন্য অস্তিত্ব নেই এমন বৈশিষ্ট্যের সীমাবদ্ধতা রয়েছে এবং বিপরীতে।

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

এক্সএক্সএক্সএক্সএক্স () / সেটএক্সএক্সএক্সএক্স () ফাংশনগুলির জন্য সিনট্যাকটিক চিনির হিসাবে বৈশিষ্ট্যগুলি ভাবেন। এভাবেই তাদের পর্দার আড়ালে বাস্তবায়ন করা হয়।


1

ক্ষেত্র এবং বৈশিষ্ট্যের মধ্যে অন্য একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে।

ডাব্লুপিএফ ব্যবহার করার সময়, আপনি কেবল সর্বজনীন বৈশিষ্ট্যগুলিতে আবদ্ধ থাকতে পারেন। পাবলিক ফিল্ডে বাঁধাই কাজ করবে না । বাস্তবায়ন না করার পরেও এটি সত্য INotifyPropertyChanged(যদিও আপনার সর্বদা হওয়া উচিত)।


DRY করা ভাল;) তবে আমি আবারও লিখি, আমি সি # ভাষায় সম্পত্তির দৃ property় ভূমিকা পছন্দ করি। জাভা তুলনায় অনেক ভাল বাস্তবায়িত হয়েছে (ফলস্বরূপ শুরু থেকে) অনেকগুলি, সম্ভবত সমস্ত নেট নেটওয়াসই কেবল বৈশিষ্ট্যগুলিতে কাজ করে। ডাব্লুপিএফ, এএসপিএক্স এবং আরও অনেক কিছু।
জেসেক সিজে

1

অন্যান্য উত্তর এবং উদাহরণগুলির মধ্যে, আমি মনে করি এই উদাহরণটি কিছু পরিস্থিতিতে কার্যকর।

উদাহরণস্বরূপ বলা যাক আপনার নিম্নলিখিত মত রয়েছে:OnChange property

public Action OnChange { get; set; }

আপনি ব্যবহার প্রতিনিধিদের করতে চান, আপনি তা পরিবর্তন প্রয়োজন চেয়ে OnChangeথেকে fieldএটি পছন্দ:

public event Action OnChange = delegate {};

এই পরিস্থিতিতে আমরা আমাদের ক্ষেত্রটিকে অযাচিত অ্যাক্সেস বা পরিবর্তন থেকে রক্ষা করি।


0

আপনার যে কোনও পাবলিক ফিল্ডের জন্য ক্ষেত্রের পরিবর্তে সর্বদা আপনার সম্পত্তি ব্যবহার করা উচিত his এটি নিশ্চিত করে যে আপনার লাইব্রেরিতে বিদ্যমান কোডগুলি ভঙ্গ না করে ভবিষ্যতে কোনও ক্ষেত্রের জন্য এনক্যাপসুলেশন প্রয়োগের দক্ষতা রয়েছে I আপনি যদি বিদ্যমান লাইব্রেরিতে বৈশিষ্ট্যগুলি সহ ক্ষেত্রগুলি প্রতিস্থাপন করেন তবে সমস্ত আপনার গ্রন্থাগার ব্যবহার করে নির্ভরশীল মডিউলগুলিও পুনরায় তৈরি করা দরকার।


"সর্বদা" কঠোর শব্দের একটি লাইটেল। সি # তে (জাভা অপেক্ষা ভাল) সম্পত্তি শক্ত অবস্থান, (সম্ভবত ব্যতিক্রম ব্যতীত) এএসপি, ডাব্লুপিএফ এবং অন্যান্যগুলিতে "বাঁধাই" এর মূল / পদ্ধতি। তবে তবুও আমি কল্পনা করতে পারি ফিল্ডের সাথে ডিজাইনের কোনও সম্পত্তিই বোধগম্য নয় (কখনও কখনও)
Jacek Cz
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.