নতুন অবজেক্ট তৈরি করবেন বা প্রতিটি সম্পত্তি রিসেট করবেন?


29
 public class MyClass
    {
        public object Prop1 { get; set; }

        public object Prop2 { get; set; }

        public object Prop3 { get; set; }
    }

ধরুন আমার কাছে একটি বস্তু myObjectরয়েছে MyClassএবং এর বৈশিষ্ট্যগুলি আমার পুনরায় সেট করতে হবে, একটি নতুন অবজেক্ট তৈরি করা বা প্রতিটি সম্পত্তি পুনর্নির্দিষ্ট করা ভাল? ধরে নিন পুরানো দৃষ্টান্তের সাথে আমার কোনও অতিরিক্ত ব্যবহার নেই।

myObject = new MyClass();

অথবা

myObject.Prop1 = null;
myObject.Prop2 = null;
myObject.Prop3 = null;


14
প্রসঙ্গ ছাড়া সত্যই উত্তর দেওয়া যায় না।
কোডসইনচওস

2
পছন্দ করেছেন সুনির্দিষ্ট উদাহরণ যেখানে নতুন অবজেক্ট তৈরি করা পছন্দনীয় নাও হতে পারে: অবজেক্ট পুলিং এবং জিসির সাথে ডিল করার জন্য বরাদ্দ হ্রাস করার চেষ্টা করা।
এক্সনার্গা হান্ট্রেস

@ XGundam05 তবে তারপরেও, এটি খুব সম্ভবত সম্ভাবনা নেই যে ওপিতে প্রস্তাবিত এই কৌশলটি এটির সাথে মোকাবিলার উপযুক্ত উপায়
বেন অ্যারনসন

2
Suppose I have an object myObject of MyClass and I need to reset its properties- যদি আপনার অবজেক্টের বৈশিষ্ট্যগুলি পুনরায় সেট করা প্রয়োজন হয় বা যদি এটি সমস্যা ডোমেনকে মডেল করতে কার্যকর হয় তবে reset()মাই ক্লাসের জন্য কোনও পদ্ধতি তৈরি করবেন না কেন । হ্যারিসনপেনের উত্তর নীচে দেখুন
ব্র্যান্ডিন

উত্তর:


49

একটি নতুন অবজেক্ট ইনস্ট্যান্ট করা সর্বদা ভাল, তারপরে আপনার কাছে বৈশিষ্ট্য (কনস্ট্রাক্টর) আরম্ভ করার জন্য 1 জায়গা রয়েছে এবং সহজেই এটি আপডেট করতে পারেন।

আপনি ক্লাসে একটি নতুন সম্পত্তি যুক্ত করার কল্পনা করুন, আপনি নতুন বৈশিষ্ট্যটি নতুন বৈশিষ্ট্য যুক্ত করার পরিবর্তে নির্মাণকারীর আপডেট করবেন যা সমস্ত বৈশিষ্ট্য পুনরায় সূচনা করে।

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


6
সম্ভাব্য তৃতীয় বিকল্প: myObject = new MyClass(oldObject);। যদিও এটি কোনও নতুন উদাহরণে আসল অবজেক্টের নির্ভুল অনুলিপি বোঝায়।
আশ্চর্যজনক ড্রিমস

আমি মনে করি যে new MyClass(oldObject)মামলাগুলির সূচনাটি ব্যয়বহুল জন্য সর্বোত্তম সমাধান।
315

8
অনুলিপি নির্মাণকারীরা আরও সি ​​++ স্টাইল। .NET কোনও ক্লোন () পদ্ধতির পক্ষে বলে মনে হচ্ছে যা একটি নতুন উদাহরণ দেয় যা হুবহু অনুলিপি।
এরিক

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

16

আপনি স্পষ্টভাবে একটি নতুন বস্তু তৈরি করা উচিৎ সুবিশাল বেশিরভাগ। সমস্ত বৈশিষ্ট্য পুনরায় অর্পণ করতে সমস্যা:

  • সমস্ত সম্পত্তিগুলিতে সর্বজনীন সেটটারগুলির প্রয়োজন, যা আপনার সরবরাহ করতে পারে এমন এনক্যাপসুলেশনের মাত্রাকে মারাত্মকভাবে সীমাবদ্ধ করে
  • পুরানো দৃষ্টান্তের জন্য আপনার অতিরিক্ত ব্যবহার রয়েছে কিনা তা জানার অর্থ আপনাকে পুরানো উদাহরণটি ব্যবহার করা হচ্ছে তা সর্বত্রই জানতে হবে। সুতরাং যদি শ্রেণি Aএবং শ্রেণি Bউভয়ই ক্লাসের দৃষ্টান্তগুলিতে পাস হয় Cতবে তাদের জানতে হবে যে তারা কখনই একই উদাহরণটি পাস করবে কিনা, এবং যদি তাই হয় তবে অন্যরা এখনও এটি ব্যবহার করছে কিনা। এই শক্তভাবে দম্পতিদের ক্লাসগুলি যা অন্যথায় হওয়ার কোনও কারণ নেই।
  • জিবিজ্বানব ইঙ্গিত হিসাবে পুনরাবৃত্ত কোডের দিকে নিয়ে যায়, আপনি যদি কনস্ট্রাক্টরের সাথে একটি প্যারামিটার যুক্ত করেন, যেখানে কনস্ট্রাক্টরকে কল করে যে কোনও জায়গায় এটি সংকলন করতে ব্যর্থ হবে, কোনও স্পট হারিয়ে যাওয়ার আশঙ্কা নেই। যদি আপনি কেবল একটি সর্বজনীন সম্পত্তি যুক্ত করেন তবে আপনাকে অবশ্যই অজানা "রিসেট" থাকা প্রতিটি জায়গাই ম্যানুয়ালি খুঁজে পেতে এবং আপডেট করতে হবে।
  • জটিলতা বাড়ে। আপনি লুপে ক্লাসের একটি উদাহরণ তৈরি এবং ব্যবহার করছেন তা কল্পনা করুন। আপনি যদি আপনার পদ্ধতি ব্যবহার করেন, তবে আপনাকে এখন প্রথমবার লুপের মাধ্যমে বা লুপটি শুরু হওয়ার আগে পৃথক আরম্ভ করতে হবে। যে কোনও উপায়ই হ'ল অতিরিক্ত কোড যা আপনাকে আরম্ভ করার এই দুটি উপায়ে সমর্থন করতে লিখতে হবে।
  • মানে আপনার শ্রেণি একটি অবৈধ অবস্থায় থাকার থেকে নিজেকে রক্ষা করতে পারে না। কল্পনা করুন যে আপনি Fractionএকটি অংক এবং ডিনোমিনেটর সহ একটি ক্লাস লিখেছেন এবং এটি প্রয়োগ করতে চেয়েছিলেন যে এটি সর্বদা হ্রাস পেয়েছে (অর্থাত্ সংখ্যার এবং গোষ্ঠীর জিসিডি ছিল 1)। আপনি যদি জনগণকে প্রকাশ্যভাবে সংখ্যা এবং ডিনোমিনেটর সেট করার অনুমতি দিতে চান তবে এটি দুর্দান্তভাবে করা অসম্ভব, কারণ তারা একটি অবৈধ রাষ্ট্রের মাধ্যমে এক বৈধ রাষ্ট্র থেকে অন্যটিতে যেতে পারে। যেমন 1/2 (বৈধ) -> 2/2 (অবৈধ) -> 2/3 (বৈধ)।
  • কোডটি বজায় রাখার জন্য যে কারও জন্য জ্ঞানীয় ঘর্ষণ বৃদ্ধি করে আপনি যে ভাষায় কাজ করছেন তার জন্য মোটেই মুশকিল নয়।

এগুলি সবই বেশ তাৎপর্যপূর্ণ সমস্যা। এবং আপনার তৈরি অতিরিক্ত কাজের বিনিময়ে আপনি যা পান তা হ'ল ... কিছুই নয় nothing অবজেক্টগুলির উদাহরণ তৈরি করা, সাধারণভাবে, অবিশ্বাস্যভাবে সস্তা, সুতরাং কার্যকারিতা সুবিধা প্রায় সর্বদা একেবারেই তুচ্ছ।

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


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

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


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

@ টেইমির সম্ভবত, তবে ওপি স্পষ্টভাবে রায় দেয় যে প্রশ্নে
বেন অ্যারনসন

9

খুব সাধারণ উদাহরণ দেওয়া, এটি বলা শক্ত। যদি "বৈশিষ্ট্যগুলি পুনরায় সেট করা" ডোমেনের ক্ষেত্রে অর্থপূর্ণ ধারণা তৈরি করে, তবে এটি আপনার শ্রেণীর গ্রাহককে কল করার জন্য আরও তাত্পর্যপূর্ণ হবে

MyObject.Reset(); // Sets all necessary properties to null

চেয়ে

MyObject = new MyClass();

আমি আপনার ক্লাস কল গ্রাহক করা প্রয়োজন হয় না

MyObject.Prop1 = null;
MyObject.Prop2 = null; // and so on

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


5

হ্যারিসন পেইন এবং ব্র্যান্ডিনের পরামর্শ অনুসারে, আমি একই জিনিসটি পুনরায় ব্যবহার করব এবং পুনরায় সেট পদ্ধতিতে বৈশিষ্ট্যগুলির আরম্ভকরণকে গুণিত করব:

public class MyClass
{
    public MyClass() { this.Reset() }

    public void Reset() {
        this.Prop1 = whatever
        this.Prop2 = you name it
        this.Prop3 = oh yeah
    }

    public object Prop1 { get; set; }

    public object Prop2 { get; set; }

    public object Prop3 { get; set; }
}

ঠিক আমি কি উত্তর দিতে চেয়েছিলাম। এটি উভয় বিশ্বের সেরা - এবং ব্যবহারের ক্ষেত্রে নির্ভর করে একমাত্র व्यवहार्य পছন্দ (ইনস্ট্যান্স-পুলিং)
ফ্যালকো

2

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

সম্পর্কিত নোটে, কয়েকটি প্যাটার্ন রয়েছে যা এমন কোনও পদ্ধতির জন্য ব্যবহার করা যেতে পারে যা কোনও বস্তুতে ডেটা ফেরত দিতে হবে:

  1. পদ্ধতি নতুন বস্তু তৈরি করে; রিটার্ন রেফারেন্স।

  2. পদ্ধতি একটি পরিবর্তনীয় অবজেক্টের একটি রেফারেন্স গ্রহণ করে এবং এটি পূরণ করে।

  3. পদ্ধতিটি refপ্যারামিটার হিসাবে একটি রেফারেন্স-টাইপ ভেরিয়েবল গ্রহণ করে এবং হয় উপযুক্ত হলে বিদ্যমান অবজেক্টটি ব্যবহার করে, বা একটি নতুন অবজেক্ট সনাক্ত করতে ভেরিয়েবল পরিবর্তন করে।

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


1

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

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

এখন বলা যাক আমার কাছে এই হাজার হাজার গাছ রয়েছে এবং আমি সেগুলি একটি লুপে মূল্যায়ন করি। এই সমস্ত ডেটা অবজেক্টগুলি একটি জিসি ট্রিগার করতে পারে এবং একটি পারফরম্যান্স হিট করতে পারে, একটি বড় একটি (আমার অ্যাপ্লিকেশনটিতে কিছু রানের জন্য 40% পর্যন্ত সিপিইউ ব্যবহারের ক্ষতি - আমি ডেটা পাওয়ার জন্য একজন প্রোফাইলার দৌড়েছি)।

একটি সম্ভাব্য সমাধান? এই ডেটা অবজেক্টগুলিকে পুনরায় ব্যবহার করুন এবং কিছু ব্যবহার করুন you're আপনি সেগুলি ব্যবহারের পরে পুনরায় সেট করুন ()। লিফ নোডগুলি আর 'নতুন ডেটা ()' কল করবে না, তারা কিছু ফ্যাক্টরি পদ্ধতি কল করবে যা বস্তুর আজীবন পরিচালনা করে।

আমি এটি জানি কারণ আমার কাছে একটি অ্যাপ্লিকেশন রয়েছে যা এই সমস্যাটিকে আঘাত করেছে এবং এটি এটি সমাধান করেছে।

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