সি # তে ব্যক্তিগত সম্পত্তি ব্যবহার করার কোনও কারণ আছে কি?


245

আমি কেবল বুঝতে পেরেছি যে সি # সম্পত্তি নির্মাণটি একটি ব্যক্তিগত অ্যাক্সেস মডিফায়ারের সাথেও ব্যবহার করা যেতে পারে :

private string Password { get; set; }

যদিও এটি প্রযুক্তিগতভাবে আকর্ষণীয়, তবে কোনও ব্যক্তিগত ক্ষেত্রের মধ্যে আরও কম অনুষ্ঠানের সাথে জড়িত হওয়ায় আমি কখন এটি ব্যবহার করব তা ভাবতে পারি না :

private string _password;

এবং কখনই অভ্যন্তরীণভাবে আমাকে সক্ষম হতে হবে তবে সেট বা সেট না করে তবে কোনও ব্যক্তিগত ক্ষেত্র না পাওয়ার দরকার হবে তা আমি ভাবতে পারি না :

private string Password { get; }

অথবা

private string Password { set; }

তবে সম্ভবত নেস্টেড / উত্তরাধিকারসূত্রে প্রাপ্ত ক্লাসগুলির সাথে ব্যবহারের কেস রয়েছে বা সম্ভবত যেখানে সম্পত্তির মান ফিরিয়ে দেওয়ার পরিবর্তে কোনও গেট / সেটটিতে যুক্তি থাকতে পারে , যদিও আমি সম্পত্তিগুলি কঠোরভাবে সরল রাখার এবং স্পষ্ট পদ্ধতিতে কোনও যুক্তি করতে দিই, যেমন GetEncodedPassword()

কেহ কোনও কারণে সি # তে ব্যক্তিগত সম্পত্তি ব্যবহার করে বা এটি কেবলমাত্র প্রযুক্তিগত-সম্ভব-এখনও-বিরল-ব্যবহৃত-আসল-কোড কনস্ট্রাক্টগুলির মধ্যে একটি?

অভিযোজ্য বস্তু

সুন্দর উত্তর, তাদের মাধ্যমে পড়তে আমি ব্যক্তিগত সম্পত্তিগুলির জন্য এই ব্যবহারগুলি উপভোগ করেছি:

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

ব্যক্তিগত সম্পত্তি দ্বারা উত্সাহিত কৌশলটি হ'ল স্বয়ং এনক্যাপসুলেশন - দেখুন: উত্স তৈরির
রিফ্যাক্টরিং

উত্তর:


212

আমি যদি একটি মান ক্যাশে প্রয়োজন এবং এটি অলস করতে চান তবে আমি সেগুলি ব্যবহার করি।

private string _password;
private string Password
{
    get
    {
        if (_password == null)
        {
            _password = CallExpensiveOperation();
        }

        return _password;
    }
}

42
এটির জন্য একটি দুর্দান্ত সাধারণ প্যাটার্নটি হ'লreturn _password ?? (_password = CallExpensiveOperation());
মার্চ

1
@ এভ্যালেক্স অলস <টি> এটি ব্যবহার করতে পারলে পছন্দনীয় হতে পারে। তবে এটি কেবল স্থির স্টাফ ব্যবহার করতে পারে, তাই আপনি (অ স্থিতিশীল) পদ্ধতি বা অন্যান্য সদস্যদের অ্যাক্সেস করতে পারবেন না। যাইহোক আমি return _password ?? (_password = CallExpensiveOperation());কিছুক্ষণ থেকেই একক লাইন বাক্য গঠন পছন্দ করি বা আসলে রিশার্পার এটিকে পছন্দ করে :)।
বার্ট

4
@ মার্ক সি # since এর পর থেকে আপনাকে গেট লিখে ফিরতে হবে না। private string Password => _password ?? (_password = CallExpensiveOperation());
অটো অমনর্মালবারব্রোচার

1
সি # 8 এর সাথে এটি আরও খাটো:private string Password => _password ??= CallExpensiveOperation();
ডেভ এম

2
@ বাস যা অলস লোডিং নয় কারণ ধারণকৃত CallExpensiveOperation();বস্তুর নির্মাণ / প্রারম্ভিককরণের সময় বলা হয় এবং যখন সম্পত্তিটি প্রথম অ্যাক্সেস করা হয় তখন নয়।
স্টিফান পডস্কুবকা

142

আমার কোডে এর প্রাথমিক ব্যবহারটি অলস সূচনা, যেমন অন্যরা উল্লেখ করেছেন।

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

মূলত, এটি নেমে আসে: কোড তথ্যের চেয়ে অনেক বেশি শক্তিশালী । যে কৌশলটি আমাকে প্রয়োজনীয় কোডটি লিখতে দেয় তা হ'ল একটি ভাল। ক্ষেত্রগুলি আপনাকে সেগুলিতে কোড লিখতে দেয় না, সম্পত্তি দেয়।


5
আপনার বক্তব্য কি "কোড ডেটার চেয়ে অনেক বেশি শক্তিশালী"? এটি গুগল করা আপনাকে উল্লেখ করে এমন রেফারেন্স দেয়। কেবল জানতে চাই যাতে আমার যখন প্রয়োজন হয় তখন আমি এটি সঠিকভাবে উদ্ধৃত করতে পারি।
জোয়ান ভেঞ্জে

24
@ জোয়ান: আমি জানি না। হয় আমি এটি তৈরি করেছি, বা আমি অন্য কাউকে এটি বলতে শুনেছি এবং ভেবে দেখেছি "বাহ, আমার এটি পুরোপুরি চুরি করা উচিত, এবং তারপরে আমি কী চুরি করেছি সে সম্পর্কে সব ভুলে যেতে হবে।"
এরিক লিপার্ট

1
+ কোডলেন্স আপনাকে জানায় কোথায় সম্পত্তিটি রেফারেন্স করা হয়েছে
UuDdLrLrSs

43

সম্ভবত নেস্টেড / উত্তরাধিকারসূত্রে প্রাপ্ত ক্লাসগুলির সাথে ব্যবহারের কেস রয়েছে বা সম্ভবত কোনও গেট / সেটটিতে সম্পত্তির মান ফিরিয়ে দেওয়ার পরিবর্তে যুক্তি থাকতে পারে

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

যদি আমি মনে করি যে কোনও সম্পত্তির অবশেষে অতিরিক্ত যুক্তি প্রয়োজন হতে পারে তবে আমি মাঝে মাঝে ক্ষেত্রটি ব্যবহার না করে এটি একটি ব্যক্তিগত সম্পত্তিতে আবদ্ধ করব, যাতে আমাকে পরে আমার কোড পরিবর্তন করতে হবে না।


একটি আধা-সম্পর্কিত ক্ষেত্রে (যদিও আপনার প্রশ্নের চেয়ে আলাদা), আমি প্রায়শই সর্বজনীন সম্পত্তিগুলিতে ব্যক্তিগত সেটটার ব্যবহার করি:

public string Password 
{
    get; 
    private set;
}

এটি আপনাকে পাবলিক গেটর দেয় তবে সেটারটি ব্যক্তিগত রাখে।


+1 উপলব্ধি করে: "যদি আমি মনে করি যে কোনও সম্পত্তির অবশেষে অতিরিক্ত যুক্তি প্রয়োজন হতে পারে তবে আমি মাঝে মাঝে ক্ষেত্রটি ব্যবহার না করে এটি একটি ব্যক্তিগত সম্পত্তিতে গুটিয়ে রাখব, সুতরাং আমাকে পরে আমার কোডটি পরিবর্তন করতে হবে না।"
এডওয়ার্ড টাঙ্গুয়ে

7
ব্যক্তিগত
সেটেটর

20

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


20

অলস সূচনাটি এমন এক জায়গা যেখানে তারা ঝরঝরে হতে পারে eg

private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */);

private MyType MyType { get { return this.mytype.Value; } }

// In C#6, you replace the last line with: private MyType MyType => myType.Value;

তারপরে আপনি লিখতে পারেন: এটি যে কোনও জায়গায় অলসভাবে তাত্ক্ষণিকভাবে স্থাপন করার this.MyTypeপরিবর্তে সর্বত্র this.mytype.Valueএবং সজ্জিত।

লজ্জার একটি বিষয় হ'ল সি # সম্পত্তির ব্যাকিং ফিল্ডটি স্কোপিং সমর্থন করে না (যেমন সম্পত্তি সংজ্ঞাের অভ্যন্তরে এটি ঘোষণা করে) এটি সম্পূর্ণরূপে আড়াল করতে এবং এটি নিশ্চিত করা যায় যে এটি কেবল কখনও সম্পত্তি দ্বারা অ্যাক্সেস করতে পারে।


2
সম্মত হয়েছিল যে সেখানে স্কোপিংয়ের দিকটি থাকবে।
ক্রিস মেরিসিক

5
আমি প্রায়শই একই কৌশলটি ব্যবহার করি এবং আমি এটিও চেয়েছিলাম যে কোনও ক্ষেত্রটি একটি কোডের বডিতে যায়। এটি একটি দুর্দান্ত বৈশিষ্ট্য কিন্তু নিম্ন অগ্রাধিকার।
এরিক লিপার্ট

5
@ এরিক লিপার্টস - field-declarationএর মধ্যে accessor-declarationsথাকা দীর্ঘসময় ধরে আমার সি # ইচ্ছার তালিকার 1 নম্বরে রয়েছে। আপনি যদি ভবিষ্যতের কিছু সংস্করণে এটি ডিজাইন ও প্রয়োগ করতে পারেন তবে আমি আপনাকে একটি কেক বেক করব।
জেফ্রি এল হুইলেটজ

13

কেবলমাত্র একটি ব্যবহার যা আমি ভাবতে পারি

private bool IsPasswordSet 
{ 
     get
     {
       return !String.IsNullOrEmpty(_password);
     }
}

অন্যান্য ব্যক্তিগত ভেরিয়েবলগুলি থেকে গুণ করা যায় এমন বৈশিষ্ট্যগুলির দরকারী শ্রেণীর জন্য +1
ড্যারেন টমাস

2
কেন একটি ব্যক্তিগত পদ্ধতি ব্যবহার করবেন নাprivate bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
রোমান

10

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

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


+1: "আপনি খুব অনুরূপ কারণে নিজের কাছে একটি
চুক্তিও

8

আমি এগুলি সিরিয়ালাইজেশনে ব্যবহার করি, যেমন DataContractSerializerপ্রোটোবুফ-নেট যা এই ব্যবহারকে সমর্থন XmlSerializerকরে ( না)। সিরিয়ালাইজেশনের অংশ হিসাবে আপনার যদি কোনও অবজেক্টকে সরল করার প্রয়োজন হয় তবে এটি কার্যকর:

public SomeComplexType SomeProp { get;set;}
[DataMember(Order=1)]
private int SomePropProxy {
    get { return SomeProp.ToInt32(); }
    set { SomeProp = SomeComplexType.FromInt32(value); }
}

6

একটি জিনিস আমি সব সময় করি তা হ'ল "গ্লোবাল" ভেরিয়েবল / ক্যাশে into HttpContext.Current

private static string SomeValue{
  get{
    if(HttpContext.Current.Items["MyClass:SomeValue"]==null){
      HttpContext.Current.Items["MyClass:SomeValue"]="";
    }
    return HttpContext.Current.Items["MyClass:SomeValue"];
  }
  set{
    HttpContext.Current.Items["MyClass:SomeValue"]=value;
  }
}

5

আমি এগুলি এখন এবং পরে প্রতিটি ব্যবহার করি। আপনি সহজে কোনও সম্পত্তিতে ব্রেকআপপয়েন্ট স্থাপন করতে পারেন বা লগিং স্টেটমেন্ট ইত্যাদি যুক্ত করতে পারলে এগুলি জিনিসগুলি ডিবাগ করা সহজ করে দেয় They

আপনার যদি পরে কোনও উপায়ে আপনার ডেটা ধরণের পরিবর্তন করতে হয় বা আপনার প্রতিবিম্ব ব্যবহার করতে হয় তবে এটি কার্যকরও হতে পারে।


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

5

আমি প্রায়শই ব্যবহার করতে হবে এমন উপ সম্পত্তিগুলিতে অ্যাক্সেসের জন্য কোড কমাতে ব্যক্তিগত সম্পত্তিগুলি ব্যবহার করি।

    private double MonitorResolution
    {
        get { return this.Computer.Accesories.Monitor.Settings.Resolution; }
    }

অনেক উপ-বৈশিষ্ট্য থাকলে এটি কার্যকর।


2

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


2

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

যদি এটি কেবল একটি সরাসরি সমর্থন ক্ষেত্র? ভাল কারণ হিসাবে কিছুই মনে আসে না।


2

আমি জানি এই প্রশ্নটি অনেক পুরানো তবে নীচের তথ্যটি বর্তমানের উত্তরের কোনওটিতে ছিল না।

আমি কখন অভ্যন্তরীণভাবে সক্ষম হতে পারি তবে সেট না করে কখনই প্রয়োজন হবে তা আমি ভাবতে পারি না

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

এছাড়াও ভিজ্যুয়াল স্টুডিও পেশাদার আপনার ক্ষেত্রটি কী ব্যবহৃত হচ্ছে তা দেখার পক্ষে ক্ষেত্রটি নয় এমন একটি সম্পত্তি সম্পর্কিত তথ্য দেবে।

PorpField


1

ভাল, কেউ যেমন উল্লেখ করেনি আপনি এটি ডেটা যাচাই করতে বা ভেরিয়েবল লক করতে ব্যবহার করতে পারেন।

  • ভ্যালিডেশন

    string _password;
    string Password
    {
        get { return _password; }
        set
        {
            // Validation logic.
            if (value.Length < 8)
            {
                throw new Exception("Password too short!");
            }
    
            _password = value;
        }
    }
  • লকিং

    object _lock = new object();
    object _lockedReference;
    object LockedReference
    { 
        get
        {
            lock (_lock)
            {
                return _lockedReference;
            }
        }
        set
        {
            lock (_lock)
            {
                _lockedReference = value;
            }
        }
    }

    দ্রষ্টব্য: কোনও রেফারেন্স লক করার সময় আপনি রেফারেন্সযুক্ত বস্তুর সদস্যদের অ্যাক্সেসটিকে লক করবেন না।

অলস রেফারেন্স: আপনি যার জন্য আজকাল নেই এটা ASYNC করতে প্রয়োজন শেষ হতে পারে যখন অলস লোড AsyncLazy । আপনি যদি ভিজ্যুয়াল স্টুডিও এসডিকে 2015 এর চেয়ে পুরানো সংস্করণে থাকেন বা এটি ব্যবহার না করে থাকেন তবে আপনি অ্যাসিঙ্কেক্সের এসিঙ্কলজিও ব্যবহার করতে পারেন ।


0

সুস্পষ্ট ক্ষেত্রগুলির আরও কিছু বহিরাগত ব্যবহারের মধ্যে রয়েছে:

  • আপনার ব্যবহার করতে হবে refবা outমান সহ - প্রয়োজন কারণ এটি একটিInterlocked কাউন্টার হিসাবে
  • এটি স্পষ্ট লেআউট সহ উদাহরণস্বরূপ মৌলিক বিন্যাস উপস্থাপনের উদ্দেশ্যে লক্ষ্য করা যায় struct(সম্ভবত কোনও সি ++ ডাম্প বা unsafeকোডে মানচিত্র দেওয়া )
  • BinaryFormatterhistorতিহাসিকভাবে এই ধরণেরটি স্বয়ংক্রিয় ক্ষেত্র হ্যান্ডলিংয়ের সাথে ব্যবহৃত হয়েছে (অটো-প্রপসে পরিবর্তিত হয়ে নাম পরিবর্তন হয় এবং এভাবে সিরিয়ালটি ভেঙে যায়)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.