ক্ষেত্রটিকে সি # তে "পঠনযোগ্য" হিসাবে চিহ্নিত করার সুবিধা কী?


295

কেবলমাত্র পঠিত হিসাবে সদস্যের পরিবর্তনশীল হওয়ার সুবিধা কী? এটি কি কেবল শ্রেণীর জীবনকালীন সময়ে কারওর মান পরিবর্তন করার বিরুদ্ধে রক্ষা করছে বা এই কীওয়ার্ডটি ব্যবহার করার ফলে কোনও গতি বা দক্ষতার উন্নতি হতে পারে?


8
বাহ্যিক উত্তরের ভাল উত্তর: dotnetperls.com/readonly
ওয়ান ওয়ার্ল্ড

3
মজাদার. এটি মূলত এই জাভা প্রশ্নের stackoverflow.com/questions/137868/… এর সি # সমতুল্য এখানে আলোচনা যদিও খুব কম উত্তপ্ত ... হুম ...
RAY

7
এটি লক্ষণীয় যে readonlyকাঠামোর ধরণের ক্ষেত্রগুলি পারস্পরিক পরিবর্তনযোগ্য ক্ষেত্রগুলির সাথে তুলনা করে পারফরম্যান্স পেনাল্টি চাপিয়ে দেয়, যেহেতু একটি readonlyমান-ধরণের ক্ষেত্রের কোনও সদস্যের অনুরোধটি ক্ষেত্রের একটি অনুলিপি তৈরি করতে এবং অনুরোধ করবে যে সদস্য।
supercat

2
পারফরম্যান্স পেনাল্টি সম্পর্কে আরও: কোড blog.jonskeet.uk/2014/07/16/…
সিএডি

উত্তর:


171

readonlyশব্দ সদস্য পরিবর্তনশীল একটি ধ্রুবক ঘোষণা করার জন্য ব্যবহার করা হয়, কিন্তু মান রানটাইম হিসাব করা করার অনুমতি দেয়। এটি সংশোধকটির সাথে ঘোষিত ধ্রুবক থেকে পৃথক হয় const, যা সংকলনের সময় এর মান সেট করতে হবে। readonlyআপনি ব্যবহার করে ক্ষেত্রের মান ঘোষণায়, বা অবজেক্টের কনস্ট্রাক্টারে সেট করতে পারেন যে ক্ষেত্রটি একটি সদস্য।

অবিচ্ছিন্নভাবে উল্লেখ করা বাহ্যিক DLL গুলি পুনরায় সংকলন করতে না চাইলে এটি ব্যবহার করুন (যেহেতু এটি সংকলনের সময় প্রতিস্থাপন হয়ে যায়)।


192

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

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

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

অপরিবর্তনীয়তার অন্যতম সুবিধা: থ্রেডিং সম্পর্কে এখানে একটি ভাল এন্ট্রি


6
আপনি যদি এটি পড়েন তবে stackoverflow.com/questions/9860595/… কেবলমাত্র পঠন সদস্যকে পরিবর্তন করা যেতে পারে এবং। নেট দ্বারা একটি অসামঞ্জস্যপূর্ণ আচরণ বলে মনে হচ্ছে
আকাশ কাভা

69

ব্যবহার করার জন্য কোনও আপাত পারফরম্যান্স সুবিধা readonlyনেই, কমপক্ষে কোনওটিই আমি এর আগে কখনও কোথাও উল্লেখ করেছি mentioned এটি আপনার পরামর্শ অনুসারে ঠিক কাজটি করার জন্য, একবার এটি শুরু করার পরে সংশোধন প্রতিরোধের জন্য।

সুতরাং এটি উপকারী যে এটি আপনাকে আরও শক্তিশালী, আরও পঠনযোগ্য কোড লিখতে সহায়তা করে। আপনি কোনও দলে কাজ করছেন বা রক্ষণাবেক্ষণের জন্য যখন এই জাতীয় জিনিসগুলির আসল উপকারটি আসে। readonlyকোডে সেই ভেরিয়েবলের ব্যবহারের জন্য একটি চুক্তি রাখার অনুরূপ কিছু হিসাবে ঘোষণা করা । মত অন্যান্য কীওয়ার্ড হিসাবে একই ভাবে ডকুমেন্টেশন যোগ হিসাবে মনে করে internalবা private, আপনি "বলছে করছি এই পরিবর্তনশীল initialisation পর পরিবর্তন করা উচিত" এবং অবশ্যই তোমরা করছি প্রয়োগ করুন।

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


এবং ওটোহ ভাষা অনুধাবন করে। তবে আপনার সুবিধার বিবৃতিটিকে অস্বীকার করছেন না।
dkretz

3
আমি সম্মত, তবে আমি মনে করি আসল উপকারটি তখনই আসে যখন একাধিক ব্যক্তি কোডটিতে কাজ করে। এটি কোডের মধ্যে একটি ছোট ডিজাইনের স্টেটমেন্ট রাখার মতো, এটির ব্যবহারের জন্য একটি চুক্তি। আমার সম্ভবত উত্তরটি দেওয়া উচিত, হি।
জিয়াওফু

7
এই উত্তর এবং আলোচনাটি আমার মতে +1
জেফ মার্টিন

@ শিয়াফু: আপনি আমাকে কেবলমাত্র হাহাহাহা সুন্দর ব্যাখ্যার ধারণার প্রতি দৃ constant়তা তৈরি করেছেন যে এই পৃথিবীতে কেউই নিবিড়তম মনের বোঝার ব্যাখ্যা দিতে পারে না
শিখর

অর্থাৎ আপনি নিজের কোডে অনড় রয়েছেন যে কোনও সময় এই মানটি পরিবর্তন করা উচিত নয়।
আন্দিজ

51

এটি খুব ব্যবহারিক পদে রাখার জন্য:

যদি আপনি dll এ এবং dll বি রেফারেন্সে কোন কনস্টেন্ট ব্যবহার করেন তবে সেই কনস্টের মান dll বিতে সংকলিত হবে আপনি যদি কনস্টের জন্য একটি নতুন মান দিয়ে dll A কে পুনরায় চালনা করেন তবে dll B এখনও মূল মানটি ব্যবহার করবে।

আপনি যদি dll A এবং dll B রেফারেন্সগুলিতে কেবলমাত্র পঠনযোগ্য ব্যবহার করেন তবে সেই পাঠ্যই সর্বদা রানটাইমের সময় সন্ধান করা হবে। এর অর্থ আপনি যদি পঠনযোগ্যর জন্য একটি নতুন মান দিয়ে dll A পুনরায় চালু করেন তবে dll B সেই নতুন মানটি ব্যবহার করবে।


4
পার্থক্যটি বোঝার জন্য এটি একটি ভাল ব্যবহারিক উদাহরণ। ধন্যবাদ।
শিজু

অন্যদিকে, constপারফরম্যান্স লাভ করতে পারে readonly। কোড সহ এখানে আরও গভীর ব্যাখ্যা দেওয়া হচ্ছে: dotnetperls.com/readonly
Dio Phung

2
আমি মনে করি সবচেয়ে বড় ব্যবহারিক শব্দটি এই উত্তরটি থেকে অনুপস্থিত: রানটাইম readonlyক্ষেত্রে ক্ষেত্রগুলিতে গণনা করা মানগুলি সঞ্চয় করার ক্ষমতা । আপনি একটি দোকান করতে পারবে না new object();একটি constকারণ আপনি এই ধরনের পরিচয় পরিবর্তন না করে কম্পাইল সময় অন্যান্য সমাহারগুলি মধ্যে রেফারেন্স অ-মান জিনিষ সেকা দিতে পারে না যে জ্ঞান করে তোলে।
বিনকি

14

একটি সম্ভাব্য কেস রয়েছে যেখানে সংকলকটি কেবল পঠনযোগ্য কীওয়ার্ডের উপস্থিতির ভিত্তিতে একটি পারফরম্যান্স অপ্টিমাইজেশন তৈরি করতে পারে।

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

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

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


এটির জন্য কি কোনও উত্স আছে?
সেদাত কাপানোগলু

4
বর্তমান জেআইটি সংকলক বাস্তবে এটি বাস্তবায়ন করে, এবং সিএলআর 3.5 এর পরে রয়েছে। github.com/dotnet/coreclr/issues/1079
mirhagk

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

9

মনে রাখবেন যে কেবলমাত্র পাঠ্যরূপে মানটি নিজেই প্রযোজ্য, সুতরাং আপনি যদি কেবল একটি রেফারেন্স টাইপ ব্যবহার করেন তবে কেবলমাত্র পড়ার জন্য রেফারেন্সটিকে পরিবর্তন থেকে রক্ষা করে। দৃষ্টান্তের রাজ্যটি কেবল পাঠ্য দ্বারা সুরক্ষিত নয়।


4

প্যারাম readonlyব্যবহার করে কোনও নির্মাণকারীর বাইরে ক্ষেত্রগুলি সেট করার জন্য কোনও কর্মসীমা আছে তা ভুলে যাবেন না out

একটু অগোছালো তবে:

private readonly int _someNumber;
private readonly string _someText;

public MyClass(int someNumber) : this(data, null)
{ }

public MyClass(int someNumber, string someText)
{
    Initialise(out _someNumber, someNumber, out _someText, someText);
}

private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText)
{
    //some logic
}

এখানে আরও আলোচনা: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx


4
ক্ষেত্রগুলি এখনও কন্সট্রাক্টরে বরাদ্দ করা হয়েছে .. এমন কোনও "আশেপাশে" নেই। মানগুলি একটি পচা জটিল ধরণের থেকে একক অভিব্যক্তি থেকে এসেছে কিনা বা কল এর মাধ্যমে রেফারেন্স শব্দার্থের দ্বারা নির্ধারিত হয়েছে তা out
বিবেচ্য নয়

এটি এমনকি প্রশ্নের উত্তর দেওয়ার চেষ্টা করে না।
শেরিডান

2

আশ্চর্যের বিষয় হল, পাঠ্যপুস্তক আসলে ধীর কোডে ফলাফল করতে পারে, যেমন জোন স্কিট তার নোদা টাইম লাইব্রেরিটি পরীক্ষা করার সময় খুঁজে পেয়েছিল। এই ক্ষেত্রে, 20 সেকেন্ডে চালিত একটি পরীক্ষা কেবলমাত্র পঠনযোগ্য অপসারণের পরে 4 সেকেন্ড সময় নিয়েছিল।

https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/


3
মনে রাখবেন যে ক্ষেত্রটি readonly structC # 7.2 তে এমন একটি প্রকারের হলে ক্ষেত্রটি অ-পঠনযোগ্য তৈরি করার সুবিধা চলে যায়।
জন স্কিটি

1

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


1

এই প্রশ্নের উত্তর দেওয়ার জন্য একটি মৌলিক দিক যুক্ত করা:

setঅপারেটরটি রেখে সম্পত্তি কেবল পঠন হিসাবে প্রকাশ করা যেতে পারে । সুতরাং বেশিরভাগ ক্ষেত্রে আপনাকে readonlyবৈশিষ্ট্যে কীওয়ার্ড যুক্ত করতে হবে না :

public int Foo { get; }  // a readonly property

এর বিপরীতে: ক্ষেত্রগুলির readonlyঅনুরূপ প্রভাব অর্জনের জন্য কীওয়ার্ডের প্রয়োজন :

public readonly int Foo; // a readonly field

সুতরাং, ক্ষেত্রটিকে চিহ্নিত করার একটি সুবিধা হ'ল অপারেটর readonlyব্যতীত সম্পত্তি হিসাবে অনুরূপ রাইনের সুরক্ষা স্তর অর্জন করা set- কোনও কারণে ক্ষেত্রটি কোনও সম্পত্তিতে পরিবর্তন না করেই, এটি পছন্দসই।


2 এর মধ্যে আচরণের মধ্যে কোনও পার্থক্য আছে?
পেট্রোস্মিম

0

ব্যক্তিগত পঠনযোগ্য অ্যারেগুলি সম্পর্কে সতর্কতা অবলম্বন করুন। এগুলি যদি কোনও ক্লায়েন্টকে অবজেক্ট হিসাবে প্রকাশ করা হয় (আপনি COM ইন্টারপের জন্য এটি আমার মতো করতে পারেন) ক্লায়েন্ট অ্যারের মানগুলি হেরফের করতে পারে। ক্লোন () পদ্ধতি ব্যবহার করুন যখন কোনও বস্তু হিসাবে কোনও অ্যারে ফিরিয়ে আনবেন।


20
না; ReadOnlyCollection<T>অ্যারের পরিবর্তে একটি এক্সপোজ করুন ।
স্ল্যাक्स

এটি কোনও মন্তব্য হওয়া উচিত উত্তর নয় কারণ এটি প্রশ্নের কোনও উত্তর দেয় না ...
পিটার

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

২০১৩ সালের হিসাবে, আপনি ব্যবহার করতে পারেন ImmutableArray<T>, যা কোনও ইন্টারফেসের ( IReadOnlyList<T>) বা বক্সিং ( ক্লাসে ReadOnlyCollection) মোড়ানো বক্সিং এড়ানো যায় । এটিতে
চার্লস টেলর

0

ডাব্লুপিএফ-তে পারফরম্যান্স সুবিধা থাকতে পারে, কারণ এটি ব্যয়বহুল DependencyProperties এর প্রয়োজনীয়তা সরিয়ে দেয়। এটি সংগ্রহগুলির সাথে বিশেষভাবে কার্যকর হতে পারে


0

কেবলমাত্র পঠনযোগ্য চিহ্নিতকরণের ব্যবহারের আর একটি আকর্ষণীয় অংশটি সিঙ্গলটনের সূচনা থেকে ক্ষেত্রটিকে রক্ষা করতে পারে।

উদাহরণস্বরূপ csharpindepth থেকে কোডে :

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}

কেবলমাত্র ফিল্ড সিঙ্গেলটনকে দু'বার আরম্ভ করা থেকে রক্ষার জন্য ছোট ভূমিকা পালন করে। আরেকটি বিশদটি হ'ল উল্লিখিত দৃশ্যের জন্য আপনি কনস্ট ব্যবহার করতে পারবেন না কারণ সংকলনের সময় কনস্টেন্টকে সৃষ্টি করতে বাধ্য করা হয়, তবে সিঙ্গলটন রান সময়ে সময় সৃষ্টি করে।


0

readonlyঘোষণার সময় সূচনা করা যেতে পারে বা শুধুমাত্র নির্মাণকারীর কাছ থেকে এর মান পেতে পারে get এর বিপরীতে constএটি শুরু করতে হবে এবং একই সাথে ঘোষণা করতে হবে। readonly সবকিছু const আছে, প্লাস কনস্ট্রাক্টর ইনিশিয়েশন

কোড https://repl.it/HvRU/1

using System;

class MainClass {
    public static void Main (string[] args) {

        Console.WriteLine(new Test().c);
        Console.WriteLine(new Test("Constructor").c);
        Console.WriteLine(new Test().ChangeC()); //Error A readonly field 
        // `MainClass.Test.c' cannot be assigned to (except in a constructor or a 
        // variable initializer)
    }


    public class Test {
        public readonly string c = "Hello World";
        public Test() {

        }

        public Test(string val) {
          c = val;
        }

        public string ChangeC() {
            c = "Method";
            return c ;
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.