সি # 3.0 অটো-প্রোপার্টি - দরকারী বা না? [বন্ধ]


155

দ্রষ্টব্য: যখন আমি সি # শুরু করছিলাম তখন এটি পোস্ট করা হয়েছিল। ২০১৪ জ্ঞানের সাথে আমি সত্যই বলতে পারি যে সি # ভাষার ক্ষেত্রে সেরা জিনিসগুলির মধ্যে স্বয়ংক্রিয় বৈশিষ্ট্যগুলি অন্যতম।

আমি ব্যক্তিগত এবং একটি সর্বজনীন ক্ষেত্র ব্যবহার করে সি # তে আমার সম্পত্তি তৈরি করতে ব্যবহৃত হচ্ছে:

private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

এখনই .NET 3.0 দিয়ে আমরা স্বতঃ-বৈশিষ্ট্য পেয়েছি:

public string Title { get; set; }

আমি জানি এটি আরও একটি দার্শনিক / বিষয়গত প্রশ্ন, তবে প্রতিটি ক্ষেত্রের জন্য পাঁচটি লাইন কোড সংরক্ষণ করা ছাড়া এই স্বয়ংক্রিয় বৈশিষ্ট্যগুলি ব্যবহার করার কোনও কারণ আছে কি? আমার ব্যক্তিগত গ্রিপ হ'ল এই বৈশিষ্ট্যগুলি আমার কাছ থেকে জিনিসগুলি গোপন করে এবং আমি কালো জাদুতে কোনও বড় অনুরাগী নই।

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

আমি সুবিধাটি দেখতে পাচ্ছি যে পরে গিটার / সেটার যুক্তি পরিবর্তন করার ক্ষমতা না হারিয়ে আমি প্রচুর কোড (এক বনাম ছয় লাইনের) সংরক্ষণ করি তবে আবার আমি ইতিমধ্যে কেবলমাত্র একটি পাবলিক ফিল্ডটিকে "পাবলিক স্ট্রিং শিরোনাম" না করে ঘোষণা করতে পারি the পেতে প্রয়োজন; সেট; } ব্লক করুন, এভাবে আরও কোড সংরক্ষণ করা saving

তো, আমি এখানে কী মিস করছি? কেন কেউ আসলে অটো-প্রোপার্টি ব্যবহার করতে চাইবে?


86
"আমার ব্যক্তিগত গ্রিপ হ'ল এই বৈশিষ্ট্যগুলি আমার কাছ থেকে জিনিসগুলি গোপন করে এবং আমি কালো জাদুতে কোনও বড় অনুরাগী নই" " তাই না? আপনি কি জানেন যে সংকলকটি আপনার কাছ থেকে সমস্ত সময় এক টোন লুকিয়ে রাখে, তাই না? আপনি অ্যাসেম্বলি না লিখলে (বা আরও সঠিকভাবে, আপনার কোডের জন্য আসল 1 এবং 0 গুলি), আপনি যা লিখছেন তা আপনার কাছ থেকে জিনিস গোপন করে।
চার্লস বায়ুং

উত্তর:


118

আমরা এগুলি সর্বদা স্ট্যাক ওভারফ্লোতে ব্যবহার করি।

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


62

হ্যাঁ, এটি কেবল কোড সংরক্ষণ করে। আপনার যখন এগুলি প্রচুর পরিমাণে থাকে তখন এটি পড়া মাইল মজাদার। এগুলি লেখার জন্য দ্রুত এবং বজায় রাখা সহজ। সেভিং কোড সর্বদা একটি ভাল লক্ষ্য।

আপনি বিভিন্ন স্কোপ সেট করতে পারেন:

public string PropertyName { get; private set; }

যাতে সম্পত্তিটি কেবল শ্রেণীর ভিতরেই পরিবর্তন করা যায়। এটি এখনও প্রতিস্থাপনযোগ্য নয় কারণ আপনি এখনও প্রতিচ্ছবিটির মাধ্যমে ব্যক্তিগত সেটারটিতে অ্যাক্সেস করতে পারেন।

সি # 6 হিসাবে আপনি প্রকৃত readonlyবৈশিষ্ট্যও তৈরি করতে পারেন - যেমন স্থাবর সম্পত্তি যা নির্মাণকারীর বাইরে পরিবর্তন করা যায় না:

public string PropertyName { get; }

public MyClass() { this.PropertyName = "whatever"; }

সংকলনের সময় যা হয়ে উঠবে:

readonly string pName;
public string PropertyName { get { return this.pName; } }

public MyClass() { this.pName = "whatever"; }

প্রচুর সদস্যের সাথে অবিচ্ছিন্ন ক্লাসে এটি প্রচুর অতিরিক্ত কোড সংরক্ষণ করে।


"সুতরাং আপনি কোনও কার্যকারিতা হারাবেন না" " আপনি কিভাবে তাদের ডিবাগ করবেন?
ওয়াল

2
@ ওয়াল - ডিবাগ করার কি আছে? সেই দৃষ্টিকোণ থেকে আপনি মূলত সদস্য ভেরিয়েবলগুলি নিয়ে কাজ করছেন।
কীথ

6
@ ওয়াল - আপনি যেমন একটি সদস্য ভেরিয়েবল অ্যাক্সেস করতে পারেন ঠিক তেমন একটি ব্রেকপয়েন্টও রাখতে পারেন, আপনি কেবল সেগুলিতে প্রবেশ করতে পারবেন না। তবে কেন আপনি চান? অটো-প্রোপার্টিগুলি আসলে যা ঘটে তা তুচ্ছ এবং স্ব-উত্পন্ন উভয়ই, যদি আপনি কোনও বাগ পেয়ে থাকেন তবে এটির সম্ভাবনা খুব কম।
কিথ

3
আমাদের এটি কিথের বাইরে নেওয়ার দরকার হতে পারে। :)
ওয়াল

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

45

বৈশিষ্ট্যগুলির পরিবর্তে ক্ষেত্রগুলি ব্যবহার করার জন্য তিনটি বড় ডাউনসাইডগুলি হ'ল:

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

7
"আপনি যদি কোনও ক্ষেত্র ব্যবহার শুরু করেন, আপনি পরে (সহজে) এগুলিকে কোনও সম্পত্তিতে পরিবর্তন করতে পারবেন না", দুঃখিত তবে কেন?
হোমাম

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

8
@ হোমাম এছাড়াও, একটি ক্ষেত্রটি একটি সম্পত্তিতে পরিবর্তন করা বাইনারি সামঞ্জস্যতা ভঙ্গ করে, ক্ষেত্রের সমস্ত গ্রাহককে পুনরায় সংযোগ করতে হবে।
ওড্রেড

1
সংশোধন এবং প্রতিবিম্ব বিষয়গুলি একপাশে রেখে, ভিজ্যুয়াল স্টুডিও ব্যবহার করে ক্ষেত্রগুলি encapsulate করা খুব সহজ: Ctrl-R + E আপনাকে উপযুক্ত ক্ষেত্র / সেটটার সহ কোনও ক্ষেত্রকে কোনও সম্পত্তিতে রূপান্তর করতে দেয়। (বা ক্ষেত্রটিতে রাইট-ক্লিক করুন, পুনরায় ফ্যাক্টর, এনক্যাপসুলেট ক্ষেত্র)।
জোব্রোকহাউস

@ হোমম ক্ষেত্রগুলি মূল্যবান (তারা পরিবর্তনশীল), এবং বৈশিষ্ট্যগুলি নয়। স্টাফ যা ক্ষেত্রের সময় সংকলিত হতে পারে এটি যখন কোনও সম্পত্তি নাও হতে পারে।
চিহ্নিত করুন

29

আমি ব্যক্তিগতভাবে অটো-সম্পত্তি পছন্দ করি। কোডের লাইনগুলি সংরক্ষণে সমস্যা কি? আপনি যদি গেটর বা সেটারগুলিতে স্টাফ করতে চান তবে এগুলি পরে সাধারণ বৈশিষ্ট্যে রূপান্তর করতে কোনও সমস্যা নেই।

যেমন আপনি বলেছিলেন যে আপনি ক্ষেত্রগুলি ব্যবহার করতে পারেন এবং আপনি যদি তাদের পরে যুক্তি যুক্ত করতে চান তবে আপনি সেগুলিকে বৈশিষ্ট্যে রূপান্তর করতে পারেন। তবে এটি প্রতিবিম্বের কোনও ব্যবহার (এবং সম্ভবত অন্য কোথাও?) নিয়ে সমস্যাগুলি উপস্থিত করতে পারে।

এছাড়াও বৈশিষ্ট্যগুলি আপনাকে গিটার এবং সেটারের জন্য পৃথক অ্যাক্সেস স্তর নির্ধারণ করতে দেয় যা আপনি কোনও ক্ষেত্রের সাথে করতে পারবেন না।

আমার ধারণা এটির মূল কীওয়ার্ডের মতোই। ব্যক্তিগত পছন্দ একটি বিষয়।


29

সি ++ এর স্রষ্টা বাজর্ন স্ট্রস্ট্রপ থেকে:

আমি বিশেষত প্রচুর গেট এবং সেট ফাংশন সহ ক্লাসগুলি অপছন্দ করি। এটি প্রায়শই ইঙ্গিত দেয় যে এটি প্রথম শ্রেণিতে হওয়া উচিত ছিল না। এটি কেবল একটি তথ্য কাঠামো। এবং যদি এটি সত্যিই কোনও ডেটা স্ট্রাকচার হয় তবে এটিকে ডেটা স্ট্রাকচার করুন।

এবং আপনি জানেন কি? সে সঠিক. আপনি গেট / সেটে কোনও প্রাইভেট ফিল্ডগুলি প্রায়শই প্রায়শই সরানো / সেট-এ গুটিয়ে রাখেন, কেবল কারণ এটি "অবজেক্ট ওরিয়েন্টেড" জিনিস। এটিই মাইক্রোসফ্টের সমস্যার সমাধান; এগুলি মূলত এমন সর্বজনীন ক্ষেত্র যা আপনি আবদ্ধ করতে পারেন।


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

18

একটি জিনিস যা উল্লেখ করেছেন বলে মনে হয় না তা হ'ল কীভাবে দুর্ভাগ্যক্রমে অটো-সম্পত্তিগুলি অপরিবর্তনীয় বস্তুর (সাধারণত অপরিবর্তনীয় স্ট্রাক্ট) কার্যকর হয় না। কারণ এর জন্য আপনার সত্যই করা উচিত:

private readonly string title;
public string Title
{
    get { return this.title; }
}

(যেখানে ক্ষেত্রটি পাসকৃত প্যারামিটারের সাহায্যে কনস্ট্রাক্টরে আরম্ভ করা হয় এবং তারপরে কেবল এটিই পড়তে হয়))

সুতরাং এটি একটি সহজ get/ private setঅটোপ্রোপার্টি এর চেয়েও সুবিধাগুলি রয়েছে।


আপনার যদি কোনও কাঠামো এতে কোনও সম্পত্তি পরিবর্তন করে থাকে তবে তার ফলে নতুন স্ট্রাক্ট আসে। আপনি কেবল অভ্যন্তরীণ স্থাবরীন রেফারেন্স টাইপ চাইলে এটি কেবল তখনই ইস্যু হয়ে উঠতে পারে - আপনার কোনও কারণ কেন দরকার হবে তা আমি দেখতে পাচ্ছি না।
কিথ

@ কিথ: আপনার প্রথম বাক্যটি সত্যই ভুল বলে মনে হচ্ছে।
ডোমেনিক

3
public string Title { get; private set; }ধরণের ফলাফল কি একই জিনিস হবে না? আপনি অবশ্যই ক্লাসের ভিতরে থেকে অবশ্যই এটি পরিবর্তন করতে সক্ষম হবেন তবে আপনি যদি তা করেন তবে আপনার অন্যান্য সমস্যাও রয়েছে ...: p
Svish

2
@Svish - যে যুক্তি কেবলমাত্র C # ওয়ার্ড দ্বারা কখনোই ব্যবহার করা উচিত কারণ তার ব্যবহার অর্থ হবে যে আমরা এই "বিভিন্ন সমস্যা" গোপন করত,
যায়েদ মাসুদ

2
আমি কেবল বোঝাতে চাইছি বাইরের এপিআই ধরণের ভিউ থেকে, এটি খুব বেশি পার্থক্য করবে না। এবং তাই চাইলে অটো-প্রোপার্টি ব্যবহার করা যেতে পারে। আপনি অবশ্যই এর মতো কিছু করতে পারলে অবশ্যই সেরা জিনিসটি হবেpublic string Title { get; private readonly set; }
Svish

12

আমি সর্বদা সর্বজনীন ক্ষেত্রের পরিবর্তে সম্পত্তি তৈরি করি কারণ আপনি কোনও ইন্টারফেস সংজ্ঞাতে বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন, আপনি কোনও ইন্টারফেস সংজ্ঞাতে সর্বজনীন ক্ষেত্রগুলি ব্যবহার করতে পারবেন না।


8

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


5

আমি অটো-প্রোপার্টি সব সময় ব্যবহার করি। সি # 3 এর আগে আমি সমস্ত টাইপিং নিয়ে বিরক্ত হতে পারিনি এবং এর পরিবর্তে কেবল সর্বজনীন ভেরিয়েবল ব্যবহার করেছি used

আমি মিস করছি কেবলমাত্র এটি করতে সক্ষম হচ্ছেন:

public string Name = "DefaultName";

আপনাকে সম্পত্তি সহ ডিফল্টগুলি আপনার নির্মাণকারীদের মধ্যে স্থানান্তর করতে হবে। দুরূহ :-(


4
সি # 6 থেকে অটো-প্রপার্টি প্রারম্ভকারীদের সাথে আপনি শীঘ্রই এটি করতে সক্ষম হবেন: public string Name { get; set; } = "DefaultName"; ব্লগস.এমএসএনএন
কার্লোস

5

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

এই ধরণের বৈশিষ্ট্যগুলি হ'ল রুবি ভাষার মতো শক্তিশালী করে তোলে (এটি এবং গতিশীল বৈশিষ্ট্য, যা অতিরিক্ত কোড হ্রাস করতে সহায়তা করে)।

রুবি এই সমস্ত পাশাপাশি রয়েছে:

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

2

তাদের সাথে আমার একটাই সমস্যা হ'ল তারা এতদূর যায় না। সংকলকের একই প্রকাশ যা স্বয়ংক্রিয় বৈশিষ্ট্য যুক্ত করেছে, আংশিক পদ্ধতি যুক্ত করেছে methods কেন তারা দুজনকে এক সাথে রাখেনি তা আমার বাইরে beyond একটি সাধারণ "<প্রপার্টিনেম আংশিক অন> পরিবর্তিত" এই জিনিসগুলিকে সত্যই দরকারী করে তুলেছিল।


আপনি অন্য পদ্ধতির ভিতরে একাধিক আংশিক পদ্ধতি রাখতে পারেন। তাদের জন্য কোনও ধরণের একটি স্বয়ং-প্যাটার্ন তৈরি করা বিভ্রান্তিকর হবে।
ম্যাথু হোয়াইট

2

এটি সহজ, এটি সংক্ষিপ্ত এবং আপনি যদি সম্পত্তিটির দেহের অভ্যন্তরে সীমার বাইরে কোনও বাস্তব বাস্তবায়ন তৈরি করতে চান তবে এটি আপনার ধরণের বাহ্যিক ইন্টারফেসটি ভেঙে দেবে না।

এর মত সহজ.


1

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


1

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

আপনি কোনও সম্পত্তির জন্য নামকরণ কনভেনশন ব্যবহার করে একটি অভ্যন্তরীণ ক্ষেত্র দিয়ে শুরু করুন । আপনি যখন প্রথম হয়

  • এর সমাবেশের বাইরে থেকে মাঠে অ্যাক্সেস প্রয়োজন, বা
  • গেটর / সেটারের সাথে যুক্তি যুক্ত করতে হবে

এটা কর:

  1. ক্ষেত্রটির নতুন নাম দিন
  2. এটি ব্যক্তিগত করুন
  3. একটি সরকারী সম্পত্তি যুক্ত করুন

আপনার ক্লায়েন্ট কোড পরিবর্তন করার প্রয়োজন হবে না।

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


0

আমি কোডআরশ ব্যবহার করি, এটি স্বয়ং-গুণাবলীর চেয়ে দ্রুত।

এটা করতে:

 private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

মোট আটটি কী-স্ট্রোক দরকার।


5
আমি যদি সিটিআরএল এবং ভি ধরে রাখি তবে আমি প্রচুর এবং প্রচুর পরিমাণে, / সত্যিই দ্রুত / পেস্ট করতে পারি, তবে এটি 'আরও ভাল' করে না। এটি কীভাবে মূল প্রশ্নের উত্তর দেয়?
জেবিআরউইলকিনসন

0

কোড স্নিপেটের সাথে একই নামের একটি অটো-সম্পত্তি মোট সাতটি কী-স্ট্রোক হবে;)


0

@ ডোমেনিক: আমি তা পাই না .. অটো-প্রোপার্টি দিয়ে আপনি এটি করতে পারবেন না ?:

public string Title { get; }

অথবা

public string Title { get; private set; }

এই আপনি উল্লেখ করা হয় কি?


আপনি করতে পারেন (দ্বিতীয়টি; পূর্ববর্তীটি সংকলন করবে না) তবে তারপরে ক্ষেত্রটি আপনার অবজেক্টের অভ্যন্তরে স্থায়ী নয়।
ডোমেনিক

সাবধানতার কথা, কেবল স্ট্রোকগুলি কেবলমাত্র যখন কেবলমাত্র পাঠ্যভাবে পতাকাঙ্কিত করা হয় কেবল তখনই অক্ষরগুলি অক্ষরযুক্ত হয়, ক্লাসগুলি কেবল অনিবার্য হয়।
গুভান্তে

0

অটো-প্রোপার্টিগুলির সাথে আমার সবচেয়ে বড় গ্রিপ হ'ল এগুলি সময় সাশ্রয়ের জন্য নকশাকৃত হয়েছে তবে আমি প্রায়শই খুঁজে পাই যে এগুলি পরে পুরো বর্ধিত বৈশিষ্ট্যে প্রসারিত করতে হবে।

ভিএস ২০০৮ যা অনুপস্থিত তা হ'ল বিস্ফোরিত অটো-প্রপার্টি রিফ্যাক্টর।

আমাদের একটি এনক্যাপসুলেট ফিল্ড রিফ্যাক্টর রয়েছে তা যেহেতু আমি কেবল সর্বজনীন ক্ষেত্রগুলি ব্যবহার করতে আরও দ্রুত কাজ করি।

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