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


41

কোনও শ্রেণীর অভ্যন্তরে কোনও ভেরিয়েবলের মান নির্ধারণ করার সময় বেশিরভাগ সময় আমাদের দুটি বিকল্পের সাথে উপস্থাপন করা হয়:

private string myValue;
public string MyValue
{
   get { return myValue; }
   set { myValue = value; }
}

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

উত্তর:


23

আমি এটিকে আরও একধাপ এগিয়ে নিয়ে যাব এবং 3 টি ক্ষেত্রে আনব। যদিও প্রতিটিতে ভিন্নতা রয়েছে, আমি সি # প্রোগ্রামিংয়ের সময় বেশিরভাগ সময় ব্যবহার করি এই নিয়ম।

2 এবং 3 ক্ষেত্রে সর্বদা সম্পত্তি অ্যাকসেসরে যান (ক্ষেত্রের পরিবর্তনশীল নয়)। এবং 1 এর ক্ষেত্রে, আপনি এই পছন্দটি করা থেকেও রক্ষা পেয়েছেন।

১) অপরিবর্তনীয় সম্পত্তি (নির্মানকারীকে দেওয়া হয়েছে, বা নির্মাণের সময় তৈরি করা হয়েছে)। এই ক্ষেত্রে, আমি কেবলমাত্র পঠনযোগ্য সম্পত্তি সহ একটি ফিল্ড ভেরিয়েবল ব্যবহার করি। আমি এটি একটি বেসরকারী সেটারের তুলনায় বেছে নিই, যেহেতু একটি প্রাইভেট সেটার অপরিবর্তনের গ্যারান্টি দেয় না।

public class Abc
{ 
  private readonly int foo;

  public Abc(int fooToUse){
    foo = fooToUse;
  }

  public int Foo { get{ return foo; } }
}

২) পোকো ভেরিয়েবল। একটি সাধারণ ভেরিয়েবল যা কোনও পাবলিক / প্রাইভেট স্কোপ / এ সেট করতে পারে। এই ক্ষেত্রে আমি কেবল একটি স্বয়ংক্রিয় সম্পত্তি ব্যবহার করব।

public class Abc
{ 
  public int Foo {get; set;}
}

৩) ভিউমোডেল বাইন্ডিং বৈশিষ্ট্য। INOTifyPropertyChanged সমর্থনকারী ক্লাসগুলির জন্য, আমার মনে হয় আপনার একটি বেসরকারী, ব্যাকিং ফিল্ড ভেরিয়েবল দরকার।

public class Abc : INotifyPropertyChanged
{
  private int foo;

  public int Foo
  {
    get { return foo; }
    set { foo = value;  OnPropertyChanged("foo"); }
  }
}

2
এমভিভিএম উদাহরণের জন্য +1। আসলে সেই প্রশ্নটিই প্রথম স্থানে সঞ্চারিত করেছিল।
এডওয়ার্ড

4
+1: এওপি-র সাথে 2/3 মিক্স করুন এবং আপনার কাছে আইএনপিসি ব্যবহারের দুর্দান্ত উপায় রয়েছে। [সূচিত করে] পাবলিক ইন ফু {get; সেট; }
স্টিভেন ইভার্স

1
@ জোব ক্লাসে অ্যাক্সেস করা যে কোনও শ্রেণীর কাছে, একটি ব্যক্তিগত সেটার অপরিবর্তনীয়তার জন্য যথেষ্ট for তবে, শ্রেণীর ভিতরে, প্রাইভেট সেটার প্রাথমিক নির্মাণের পরে, মানটির পুনরাবৃত্তি সেটিংস প্রতিরোধ করে না। 'প্রাইভেট রিডোনলি সেট'-এর মতো একটি ভাষা বৈশিষ্ট্যটি এই সমস্যাটি নিয়ে ধারণাগতভাবে কাজ করতে পারে তবে এটি বিদ্যমান নেই।
শেল্ডন ওয়ার্কেন্টিন

1
আমি সি # তে নতুন, তাই বলুন, এর পরিবর্তে কেন ব্যবহার করবেন ? public int Foo {get; set;}public int Foo

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

18

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

এটি অবশ্যই কোনও পারফরম্যান্স ফ্যাক্টর নয়। অপ্টিমাইজার আপনার জন্য একটি সহজ প্রাপ্ত বা সেটটিকে ইনলাইন করবে এবং চূড়ান্ত এমএসআইএল কোড সম্ভবত অভিন্ন হবে।


নির্মাণকারীর ক্ষেত্রটি ব্যবহারের কোনও বিশেষ কারণ? অদ্ভুত পার্শ্ব প্রতিক্রিয়া কম সম্ভাবনা?
স্বাক্ষর করুন

4
@ সাইন: আমার অনুমান যে সম্পত্তিটির (যদি এখন বা ভবিষ্যতে) বৈধতা থাকে তবে আপনি নির্মাণের সময় ব্যর্থতা বৈধ হওয়ার ঝুঁকিটি চালাতে চান না। বৈধতা এই পর্যায়ে যৌক্তিক নয় কারণ কনস্ট্রাক্টর শেষ না হওয়া পর্যন্ত অবজেক্টটি স্থিতিশীল হওয়ার গ্যারান্টি দেওয়া যায় না।
স্টিভেন এভার্স 20

@ সাইন: আপনি যা বলেছিলেন এবং স্নারফাস কী বলেছেন উভয়ই। বা যদি আমি কোনও সম্পত্তিতে পরিবর্তনগুলি লগ করতে চাই তবে আমি সম্ভবত প্রাথমিক সেটিংটি লগ করতে চাই না। তবে, আমি "সাধারণভাবে" বলেছিলাম।
pdr

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

4

নির্ভর করে।

প্রথমে আপনার যখন সম্ভব হয় তখন স্বয়ংক্রিয় বৈশিষ্ট্যগুলি পছন্দ করা উচিত:

public string MyValue {get;set;}

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

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


3
আমি পছন্দ করতে public string MyValue {get; private set;}
কাজ

3

ঠিক আছে, সোজা-থেকে-দফার পন্থাটি কেবল এটি কেবলমাত্র ভেরিয়েবলকে অর্পণ করা হবে, যেহেতু আপনি কোনও শ্রেণীর অভ্যন্তরে আছেন 'পদ্ধতি এবং আপনি যেভাবেই ক্লাস নিয়ন্ত্রণ করতে পারেন' behavior

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

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


2

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

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


2

আমি সর্বদা জনসাধারণের সম্পত্তি ব্যবহার করি।

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

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


+1 হ্যাঁ বেশিরভাগ ক্ষেত্রে (এমভিভিএম) প্রপার্টি চেঞ্জ করা ইভেন্টটি আবশ্যক। এবং এটি কেবল কোনও সম্পত্তির ভিতরেই বরখাস্ত হতে পারে। ভাল ব্যাখ্যা।
এডওয়ার্ড

1

সাধারণত / সেট করার সময় কোনও সম্পত্তি এবং এর ব্যাকিং ফিল্ডটি নিয়ে আপনার কী করা উচিত তা আপনার বিষয়।

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

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


0

সর্বদা এটি যে ব্যবহার করে তা ব্যবহার করুন use হ্যাঁ, আমি জানি যে উত্তরহীন হওয়ার দিক থেকে বেশ বগু লাগছে।

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

public Foo Bar
{
  get { return _bar; }
  set { _bar = doSomethingTo(value); }
}

তবে অন্যান্য পরিস্থিতিতে আপনি কেবল কোনও ডেটা মডেলের ভিউ হিসাবে কোনও সম্পত্তি ব্যবহার করছেন:

public Double SomeAngleDegrees
{
  get { return SomeAngleRadians * 180 / PI; }
  set { SomeAngleRadians = value * PI / 180; }
}

যদি রেডিয়ানের ফর্মটি ব্যবহার করে তা বোধগম্য হয় SomeAngle, তবে যেকোন উপায়ে এটি ব্যবহার করুন।

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

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