যাত্রী, সেটার এবং বৈশিষ্ট্যগুলি সর্বোত্তম অনুশীলন। জাভা বনাম সি #


92

আমি এখনই একটি সি # ক্লাস নিচ্ছি এবং আমি কাজ করার সর্বোত্তম উপায়টি সন্ধান করার চেষ্টা করছি। আমি জাভা ব্যাকগ্রাউন্ড থেকে এসেছি এবং তাই আমি কেবল জাভা সেরা-অনুশীলনের সাথে পরিচিত; আমি সি # নবাগত!

জাভাতে যদি আমার ব্যক্তিগত সম্পত্তি থাকে তবে আমি এটি করি;

private String name;

public void setName(String name) {
   this.name = name;
}

public String getName() {
   return this.name;
}

সি # তে, আমি দেখতে পাচ্ছি যে এটি করার অনেকগুলি উপায় রয়েছে।

আমি জাভা এর মত এটি করতে পারি:

private string name;

public void setName(string name) {
   this.name = name;
}

public string getName() {
   return this.name;
}

বা আমি এটি এইভাবে করতে পারি:

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}

বা:

public string Name { get; set; }

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

সম্পাদনা

জন স্কিটির উত্তরের মন্তব্য হিসাবে আমি এটি পোস্ট করছিলাম তবে এটি দীর্ঘ হয়ে গেল:

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

উত্তর:


88

প্রাক-সি # 6

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

অপ্রয়োজনীয়তা স্বয়ংক্রিয়ভাবে প্রয়োগ হওয়া বৈশিষ্ট্যগুলির সাথে কিছুটা ব্যথা হয় - আপনি কোনও স্বয়ং-সম্পত্তি লিখতে পারবেন না যার কেবল প্রাপ্তি রয়েছে; আপনি যে নিকটে আসতে পারেন তা হ'ল:

public string Foo { get; private set; }

যা সত্যিই অপরিবর্তনীয় নয় ... কেবল আপনার শ্রেণীর বাইরে অপরিবর্তনীয়। সুতরাং আপনি পরিবর্তে একটি বাস্তব পঠনযোগ্য সম্পত্তি ব্যবহার করতে চাইতে পারেন :

private readonly string foo;
public string Foo { get { return foo; } }

আপনি অবশ্যই লিখতে চান না getName()এবং setName()। ইন কিছু ক্ষেত্রে এটা ক্লিক করুন / সেট বদলে বৈশিষ্ট্য ব্যবহার পদ্ধতি জ্ঞান করে তোলে, বিশেষ করে যদি তারা ব্যয়বহুল হতে পারে এবং আপনি যে জোর দেওয়া করতে ইচ্ছুক। যাইহোক, আপনি পদ্ধতিগুলির জন্য পাস্কেলকেসে NET নামকরণের সম্মেলনটি অনুসরণ করতে চাইবেন এবং আপনি চাইবেন না যে এর মতো একটি তুচ্ছ সম্পত্তি কোনওভাবেই সাধারণ পদ্ধতিতে প্রয়োগ করা হোক - একটি সম্পত্তি এখানে আরও বেশি বুদ্ধিমান।

সি # 6

হুরে, আমাদের কাছে অবশেষে যথাযথ পঠনযোগ্য কেবল স্বয়ংক্রিয়ভাবে প্রয়োগ করা বৈশিষ্ট্য রয়েছে:

// This can only be assigned to within the constructor
public string Foo { get; }

একইভাবে শুধুমাত্র পাঠযোগ্য বৈশিষ্ট্য, যার জন্য কি করতে প্রয়োজন কিছু কাজ করার জন্য, আপনাকে সদস্য-সাকার বৈশিষ্ট্য ব্যবহার করতে পারেন:

public double Area => height * width;

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

4
আমার মনে হয় সুসংবাদটি আমার প্রতিক্রিয়াটি আপনার উল্লেখ করা কোনও কিছুর বিরোধিতা বলে মনে হচ্ছে না। খারাপ খবরটি হ'ল আপনার আঙ্গুলগুলি আমার চেয়ে অনেক দ্রুত। দুর্দান্ত অন্তর্দৃষ্টি, এবং যুক্ত বিশদ জন্য ধন্যবাদ।
jeremyalan

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

4
@ আর্টিন্দ্রু: হ্যাঁ, আমি এটি সম্পর্কে অবহিত। কেবলমাত্র পঠনযোগ্য সম্পত্তি লেখা সম্পূর্ণভাবে সম্ভব। তবে আপনি সেট অ্যাক্সেসর ব্যতীত স্বয়ংক্রিয়ভাবে প্রয়োগ করা সম্পত্তি ঘোষণা করতে পারবেন না ।
জন স্কিটি


17

আপনার যদি প্রয়োজন কেবল কিছু ডেটা সঞ্চয় করার জন্য ভেরিয়েবল হয়:

public string Name { get; set; }

এটি কেবল পঠনযোগ্য হিসাবে প্রদর্শিত করতে চান?

public string Name { get; private set; }

বা আরও ভাল ...

private readonly string _name;

...

public string Name { get { return _name; } }

সম্পত্তি বরাদ্দের আগে কিছু মান চেক করতে চান?

public string Name 
{
   get { return m_name; }
   set
   {
      if (value == null)
         throw new ArgumentNullException("value");

      m_name = value;
   }
}

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


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

4
প্রাইভেট সেটার! = অপরিবর্তনীয়
পিয়াদার 15'15

পিয়াদার ঠিক আছে। একটি প্রাইভেট সেটারের অর্থ হ'ল আমি অ্যাসাইনমেন্ট করতে পারি না, তবে আমি এখনও ব্যবহার করতে পারি myList.Add(), উদাহরণস্বরূপ (যতক্ষণ না অবজেক্টটি পরিবর্তিত হওয়ার বিষয়টি প্রকাশিত হয় ততক্ষণ এটি পরিবর্তনীয়)।

4
@ ফ্লিনবার্গ দুঃখিত তবে আমি একমত নই ... আপনি যদি কোনও মান Min/ Maxমান সহ একটি অগ্রগতি বার পেয়ে থাকেন তবে কী হবে । আপনি তা নিশ্চিত করতে চান Max > Min? একটি SetRange(Min, Max)বোধগম্যতা থাকতে পারে তবে আপনি কীভাবে সেই মানগুলি আবার পড়তে যাচ্ছেন? পঠনযোগ্য ন্যূনতম / সর্বোচ্চ বৈশিষ্ট্য? অবৈধ ইনপুট জন্য ব্যতিক্রম ছোঁড়া এটি হ্যান্ডেল করার সবচেয়ে পরিষ্কার উপায় মত মনে হয়।
বেসিক

12

সি / তে বৈশিষ্ট্যগুলি ব্যবহার করুন, / সেট পদ্ধতিগুলি পাবেন না। তারা আপনার সুবিধার্থে সেখানে রয়েছে এবং এটি মূর্তিমান।

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


5

সি # তে প্রাপ্ত এবং / অথবা সেটটির জন্য ব্যক্তিগত ক্ষেত্রগুলি উন্মুক্ত করার জন্য বৈশিষ্ট্যগুলি পছন্দ করে। আপনি যে থিমটি উল্লেখ করেছেন তা হ'ল একটি স্বতঃসম্পর্কিত যেখানে পাবেন এবং সেটটি স্বয়ংক্রিয়ভাবে আপনার জন্য একটি লুকানো পিভট ব্যাকিং ফিল্ড তৈরি করে।

আমি যখন সম্ভব সম্ভব অটো বৈশিষ্ট্যগুলির পক্ষে থাকি তবে আপনার কখনই সি # তে কোনও সেট / প্যাটার্ন পেয়ার করা উচিত নয়।


5
public string Name { get; set; }

এটি কেবল একটি স্ব-বাস্তবায়িত সম্পত্তি এবং প্রযুক্তিগতভাবে একটি সাধারণ সম্পত্তি হিসাবে একই same সংকলন করার সময় একটি ব্যাকিং ফিল্ড তৈরি করা হবে।

সমস্ত বৈশিষ্ট্যগুলি শেষ পর্যন্ত ফাংশনে রূপান্তরিত হয়, সুতরাং শেষের প্রকৃত সংকলন বাস্তবায়ন আপনি জাভাতে যেমন অভ্যস্ত হন তেমনই হয়।

যখন আপনাকে ব্যাকিং ফিল্ডে নির্দিষ্ট ক্রিয়াকলাপ করতে হবে না তখন স্বয়ংক্রিয়-প্রয়োগকৃত বৈশিষ্ট্যগুলি ব্যবহার করুন। অন্যথায় একটি সাধারণ সম্পত্তি ব্যবহার করুন। যখন অপারেশনের পার্শ্ব প্রতিক্রিয়া হয় বা কম্পিউটেশনালি ব্যয়বহুল হয় তখন গেট অ্যান্ড ফাংশনগুলি ব্যবহার করুন, অন্যথায় বৈশিষ্ট্যগুলি ব্যবহার করুন।


4

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

ব্যক্তিগতভাবে আমি অটো-বৈশিষ্ট্যগুলি বেছে নেব, শেষ সংস্করণ: public string Name { get; set; }যেহেতু তারা কমপক্ষে স্থান নেয়। এবং যদি আপনার বৈধতার মতো কিছু যুক্ত করার প্রয়োজন হয় তবে আপনি ভবিষ্যতে এগুলি সর্বদা প্রসারিত করতে পারেন।


4

যখনই সম্ভব আমি জনসাধারণকে string Name { get; set; }এটি পছন্দ করি এবং এটি সহজেই পাঠযোগ্য। যাইহোক, অনেক সময় এটি প্রয়োজন যখন হতে পারে

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}

4
কখন এবং কেন এই জাতীয় জিনিসটি প্রয়োজনীয় তা আপনি ব্যাখ্যা করতে পারেন?
জেস্পার

এই মুহুর্তে আমি ২ য় সংস্করণ ব্যবহারের কারণটি ভাবতে পারি না। আমি কেবল বলেছিলাম 'এটি যখন প্রয়োজন তখন হতে পারে'। আমি ইতিবাচক না হলে অবাস্তব ব্যবহার করতে আমি ঘৃণা করি।
স্কুইডসার্কে

4
আর কেন এই 'লোলজ'? আপনি আপগেট করে একটি মন্তব্যের জন্য আপনার সমর্থন প্রদর্শন করতে পারেন।
স্কুইডসার্কে

4
সুস্পষ্ট ব্যাকিং ফিল্ডটি ব্যবহার করার একটি কারণ হ'ল আপনি যখন মানটির বিরুদ্ধে পারমাণবিক / থ্রেড-নিরাপদ অপারেশন করতে চান
বেসিক

4

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

public boolean MyProperty
{
    get { return something; }
}

public boolean MyProperty
{
    set { this.something = value; }
}

4

প্রথমে আপনি যা লিখেছেন তা বোঝানোর চেষ্টা করি:

// private member -- not a property
private string name;

/// public method -- not a property
public void setName(string name) {
   this.name = name;
}

/// public method -- not a property
public string getName() {
   return this.name;
}

// yes it is property structure before .Net 3.0
private string name;
public string Name {
   get { return name; }
   set { name = value; }
}

এই কাঠামোটি আজকাল ব্যবহৃত হয় তবে আপনি যদি কিছু অতিরিক্ত কার্যকারিতা করতে চান তবে এটি সবচেয়ে উপযুক্ত।

.NET ফ্রেমওয়ার্ক 3.0 দিয়ে

// this style is introduced, which is more common, and suppose to be best
public string Name { get; set; }

//You can more customize it
public string Name
{
    get;
    private set;    // means value could be set internally, and accessed through out
}

সি # তে আপনার আরও ভাগ্য কামনা


3

যেমনটি উল্লেখ করা হয়েছে, এই সমস্ত পদ্ধতির ফলাফল একই ফলাফল হিসাবে ঘটে। সর্বাধিক গুরুত্বপূর্ণ বিষয়টি হল আপনি একটি সম্মেলন বেছে নিন এবং এটির সাথে আঁকুন। আমি শেষ দুটি সম্পত্তি উদাহরণ ব্যবহার করতে পছন্দ করি।


2

এখানে বেশিরভাগ উত্তরের মতো, স্বয়ংক্রিয় বৈশিষ্ট্যগুলি ব্যবহার করুন। স্বজ্ঞাত, কোডের কম লাইন এবং এটি আরও পরিষ্কার। যদি আপনার ক্লাসটি সিরিয়াল করা উচিত তবে শ্রেণিটি [Serializable]/ [DataConract]বৈশিষ্ট্য সহ চিহ্নিত করুন । এবং যদি আপনি [DataContract]সদস্যটি ব্যবহার করে চিহ্নিত করেন

[DataMember(Name="aMoreFriendlyName")]
public string Name { get; set; }

ব্যক্তিগত বা পাবলিক সেটার আপনার পছন্দ উপর নির্ভর করে।

এছাড়াও নোট করুন যে স্বয়ংক্রিয় বৈশিষ্ট্যগুলির জন্য উভয় গ্রাহক এবং সেটটার (পাবলিক বা ব্যক্তিগত) প্রয়োজন।

/*this is invalid*/
public string Name 
{ 
    get; 
   /* setter omitted to prove the point*/
}

বিকল্পভাবে, আপনি যদি কেবল পেতে / সেট করতে চান তবে নিজেই একটি ব্যাকিং ফিল্ড তৈরি করুন


0

আমার কোনটি ব্যবহার করা উচিত এবং প্রতিটি পদ্ধতির সাথে জড়িত সাবধানতা বা সূক্ষ্মতাগুলি কী কী?

বৈশিষ্ট্যগুলির সাথে যাওয়ার সময় একটি সতর্কতা অবলম্বন করা হয় যা এখনও উল্লেখ করা হয়নি: বৈশিষ্ট্যগুলির সাথে আপনার গেটার বা সেটটারগুলির কোনও প্যারামিট্রাইজেশন থাকতে পারে না।

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

obj.getItems(filter);

বিপরীতে, একটি সম্পত্তি সহ আপনি প্রথমে সমস্ত আইটেম ফিরিয়ে দিতে বাধ্য হন

obj.items

এবং তারপরে পরবর্তী ধাপে ফিল্টারটি প্রয়োগ করুন বা আপনাকে উত্সর্গীকৃত বৈশিষ্ট্য যুক্ত করতে হবে যা বিভিন্ন মানদণ্ডের দ্বারা ছাঁকানো আইটেমগুলি প্রকাশ করে, যা শীঘ্রই আপনার এপিআইকে ব্লাস্ট করে:

obj.itemsFilteredByX
obj.itemsFilteredByY

যখন আপনি কোনও সম্পত্তি দিয়ে শুরু করেছিলেন তখন কখনও কখনও উপদ্রব হতে পারে যা উদাহরণস্বরূপ obj.itemsএবং পরে আবিষ্কার করেছেন যে গেটর- বা সেটার-প্যারামিট্রাইজেশন প্রয়োজন বা শ্রেণি-এপিআই ব্যবহারকারীর জন্য জিনিসগুলি সহজ করে তুলবে। আপনাকে এখন আপনার API টি পুনর্লিখন করতে হবে এবং আপনার কোডটিতে এই সম্পত্তিটি অ্যাক্সেস করতে পারে এমন সমস্ত জায়গাগুলি সংশোধন করতে হবে বা বিকল্প সমাধান খুঁজে পেতে হবে। বিপরীতে, একটি গেট-মেথডের সাথে, উদাহরণস্বরূপ obj.getItems(), একটি বিকল্প "কনফিগারেশন" অবজেক্ট গ্রহণ করার জন্য আপনি কেবল আপনার পদ্ধতির স্বাক্ষর প্রসারিত করতে পারেন , যেমন obj.getItems(options)আপনার পদ্ধতিটিকে কল করে এমন সমস্ত জায়গাগুলি পুনরায় লিখিত না করে।

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

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