ক্লোন (বনাম) নির্মাণকারী অনুলিপি করুন


119

সি # তে, কোনও ক্লাসে (গভীর) অনুলিপি কার্যকারিতা যুক্ত করার পছন্দের উপায়টি কী? কেউ কি অনুলিপি নির্মাণকারীকে বাস্তবায়ন করতে পারে, না বরং পদ্ধতিটি থেকে উদ্ভূত ICloneableএবং প্রয়োগ করতে হবে Clone()?

মন্তব্য : আমি বন্ধনীর মধ্যে "গভীর" লিখেছিলাম কারণ আমি ভেবেছিলাম এটি অপ্রাসঙ্গিক। স্পষ্টতই অন্যরা দ্বিমত পোষন করে, তাই আমি জিজ্ঞাসা করেছি যে কোনও অনুলিপি নির্মাণকারী / অপারেটর / ফাংশনটি কোন অনুলিপিটি প্রয়োগ করে তা পরিষ্কার করা দরকার ।

উত্তর:


91

আপনি থেকে প্রাপ্ত করা উচিত নয় ICloneable।

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

পরিবর্তে, আপনার (এবং ) পদ্ধতিগুলির সাথে আপনার নিজের IDeepCloneable(এবং IShallowCloneable) ইন্টারফেসগুলি সংজ্ঞায়িত করা উচিত ।DeepClone()ShallowClone()

আপনি দুটি ইন্টারফেস সংজ্ঞায়িত করতে পারেন, একটি জেনেরিক প্যারামিটার সহ দৃ strongly়ভাবে টাইপযুক্ত ক্লোনিং সমর্থন করার জন্য এবং একটি যখন আপনি বিভিন্ন ধরণের ক্লোনযোগ্য বস্তুর সংগ্রহ নিয়ে কাজ করছেন তখন দুর্বলভাবে টাইপযুক্ত ক্লোনিং ক্ষমতা না রেখে:

public interface IDeepCloneable
{
    object DeepClone();
}
public interface IDeepCloneable<T> : IDeepCloneable
{
    T DeepClone();
}

যা আপনি এর পরে প্রয়োগ করবেন:

public class SampleClass : IDeepCloneable<SampleClass>
{
    public SampleClass DeepClone()
    {
        // Deep clone your object
        return ...;
    }
    object IDeepCloneable.DeepClone()   
    {
        return this.DeepClone();
    }
}

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

এটি নেট ফ্রেমওয়ার্ক ডিজাইন গাইডলাইন এবং ব্র্যাড আব্রামসের ব্লগে আলোচনা করা হয়েছে

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


2
আপনি যদি কোনও ইন্টারফেসের জন্য যাচ্ছেন তবে ডিপক্লোন (টি এর) () এবং ডিপক্লোন (টি) এর (টি হিসাবে ডামি) কীভাবে উভয়ই টি ফিরে আসবে? পরের সিনট্যাক্সটি আর্গুমেন্টের উপর ভিত্তি করে টি অনুমান করা মঞ্জুরি দেয়।
— সুপারক্যাট

@ সুপের্যাট: আপনি কি বলছেন যে একটি ডামি প্যারামিটার রয়েছে যাতে টাইপটি অনুমান করা যায়? আমি মনে করি এটি একটি বিকল্প। আমি নিশ্চিত নই যে টাইপটি স্বয়ংক্রিয়ভাবে অনুমান করা যায় বলে আমি একটি ডামি প্যারামিটার পছন্দ করি। সম্ভবত আমি আপনাকে ভুল বোঝাবুঝি করছি। (সম্ভবত একটি নতুন উত্তরে কিছু কোড পোস্ট করুন যাতে আপনি কী বলতে চাইছেন তা আমি দেখতে পাচ্ছি)।
— সাইমন পি স্টিভেন্স

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

2
প্রশ্ন! আপনি কোন পরিস্থিতিতে নন জেনেরিক সংস্করণটি চান? আমার কাছে এটি কেবলমাত্র IDeepCloneable<T>অস্তিত্বের জন্যই বোধগম্য , কারণ ... আপনি কী জানেন টি যদি আপনি নিজের বাস্তবায়ন করেন, যেমনSomeClass : IDeepCloneable<SomeClass> { ... }
— কাইল বারান

2
@ কাইল বলছেন আপনার কাছে এমন একটি পদ্ধতি ছিল যা ক্লোনযোগ্য বস্তু গ্রহণ করেছিল MyFunc(IDeepClonable data), তবে এটি কেবল কোনও নির্দিষ্ট ধরণের নয়, সমস্ত ক্লোনবেলে কাজ করতে পারে। অথবা আপনার কাছে ক্লোনবেবলের সংগ্রহ থাকলে। IEnumerable<IDeepClonable> lotsOfCloneablesতাহলে আপনি একই সাথে প্রচুর অবজেক্টের ক্লোন করতে পারেন could যদিও আপনার যদি এই ধরণের জিনিসটির প্রয়োজন না হয় তবে অ-জেনেরিকটি ছেড়ে দিন।
— সাইমন পি স্টিভেন্স

33

সি # তে, কোনও ক্লাসে (গভীর) অনুলিপি কার্যকারিতা যুক্ত করার পছন্দের উপায়টি কী? কেউ কি অনুলিপি নির্মাণকারীকে বাস্তবায়ন করতে পারেন, বা আইসিএলনেবল থেকে উদ্ভূত হওয়া এবং ক্লোন () পদ্ধতিটি বাস্তবায়ন করতে হবে?

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

একটি অনুলিপি কনডাক্টর ICloneable এর মধ্যে একটি সমস্যা থেকেও ভোগেন। কোনও অনুলিপি নির্মাণকারী গভীর বা অগভীর অনুলিপি করছেন কিনা তা সুস্পষ্ট নয়।

Account clonedAccount = new Account(currentAccount); // Deep or shallow?

ডিপক্লোন () পদ্ধতি তৈরি করা ভাল। এই উদ্দেশ্যটি পুরোপুরি পরিষ্কার।

এটি একটি স্ট্যাটিক বা উদাহরণ পদ্ধতি হওয়া উচিত কিনা তা নিয়ে প্রশ্ন উত্থাপন করে।

Account clonedAccount = currentAccount.DeepClone();  // instance method

অথবা

Account clonedAccount = Account.DeepClone(currentAccount); // static method

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

class CheckingAccount : Account
{
    CheckAuthorizationScheme checkAuthorizationScheme;

    public override Account DeepClone()
    {
        CheckingAccount clone = new CheckingAccount();
        DeepCloneFields(clone);
        return clone;
    }

    protected override void DeepCloneFields(Account clone)
    {
        base.DeepCloneFields(clone);

        ((CheckingAccount)clone).checkAuthorizationScheme = this.checkAuthorizationScheme.DeepClone();
    }
}

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

11
আমি এখানে পয়েন্টগুলিতে তর্ক করতে যাচ্ছি না, তবে আমার মতে, কলোন () কে কল করলে কলকারীকে গভীর বা অগভীর বিষয়ে এতটা যত্ন নেওয়া উচিত নয়। তাদের জানা উচিত যে তারা কোনও অবৈধ ভাগ করে নেওয়া-রাষ্ট্রের সাথে একটি ক্লোন পাচ্ছেন। উদাহরণস্বরূপ, এটি পুরোপুরি সম্ভব যে একটি গভীর ক্লোনায় আমি প্রতিটি উপাদানকে গভীরভাবে ক্লোন করতে চাই না। ক্লোনটির কলকারীকে যে সমস্ত বিষয় বিবেচনা করা উচিত তা হ'ল তারা একটি নতুন অনুলিপি পাচ্ছেন যার মূলটির সাথে কোনও অবৈধ এবং অসমর্থিত উল্লেখ নেই। পদ্ধতি 'DeepClone "কল করা হচ্ছে কলারের কাছে অত্যধিক বাস্তবায়ন বিস্তারিত বহন করা বলে মনে হয়।
— zumalifeguard

1
স্থির পদ্ধতি দ্বারা অনুলিপি না করে কীভাবে নিজেকে ক্লোন করতে হবে তা জেনে কোনও অবজেক্টের দোষ কী? এটি জৈবিক কোষগুলির সাথে সমস্ত সময় আসল বিশ্বে ঘটে। আপনার নিজের দেহের কক্ষগুলি এই মুহুর্তে পড়ার সাথে সাথে নিজেকে ক্লোন করতে ব্যস্ত। আইএমও, স্ট্যাটিক পদ্ধতির বিকল্পটি আরও জটিল।
— কেন বেকেট

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

23

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

আপনার যদি পলিমর্ফিক ক্লোনিংয়ের প্রয়োজন হয় তবে আপনি অনুলিপি নির্মাণকারীকে কল দিয়ে আপনার বেস ক্লাসে এমন একটি abstractবা virtual Clone()পদ্ধতি যুক্ত করতে পারেন যা আপনি প্রয়োগ করেন।

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

উদা:

public class BaseType {
   readonly int mBaseField;

   public BaseType(BaseType pSource) =>
      mBaseField = pSource.mBaseField;

   public virtual BaseType Clone() =>
      new BaseType(this);
}

public class SubType : BaseType {
   readonly int mSubField;

   public SubType(SubType pSource)
   : base(pSource) =>
      mSubField = pSource.mSubField;

   public override BaseType Clone() =>
      new SubType(this);
}

8
পলিমর্ফিক ক্লোনিংয়ের জন্য +1; ক্লোনিংয়ের একটি উল্লেখযোগ্য প্রয়োগ
— সামিস

18

একটি দুর্দান্ত যুক্তি রয়েছে যে আপনার সুরক্ষিত অনুলিপি নির্মাণকারী ব্যবহার করে ক্লোন () প্রয়োগ করা উচিত

কোনও সুরক্ষিত (জন-প্রকাশ্য) অনুলিপি নির্মাণকারী সরবরাহ করা এবং ক্লোন পদ্ধতি থেকে এটি প্রার্থনা করা ভাল better এটি আমাদেরকে কোনও শ্রেণীর নিজের উদাহরণে কোনও বস্তু তৈরির কাজটি অর্পণ করার ক্ষমতা দেয়, এভাবে এক্সটেনসিবিলিটি সরবরাহ করে এবং সুরক্ষিত অনুলিপি নির্মাণকারী ব্যবহার করে সুরক্ষিতভাবে তৈরি করে।

সুতরাং এটি কোনও "বনাম" প্রশ্ন নয়। এটি সঠিকভাবে করার জন্য আপনার উভয় অনুলিপি নির্মাণকারী (গুলি) এবং একটি ক্লোন ইন্টারফেসের প্রয়োজন হতে পারে।

(যদিও প্রস্তাবিত পাবলিক ইন্টারফেসটি কনস্ট্রাক্টর ভিত্তিক না হয়ে ক্লোন () ইন্টারফেস is

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

ক্লোন () চুক্তিটি কেবল "যখন আমি প্রথমটি পরিবর্তন করি তখন পরিবর্তন হবে না" is আপনার কতটা গ্রাফ অনুলিপি করতে হবে, বা কীভাবে আপনি তা ঘটানোর জন্য অসীম পুনরাবৃত্তি এড়াবেন তা কলারের উদ্বেগের বিষয় নয়।


"কলারের উদ্বেগ হওয়া উচিত নয়"। আমি আরও একমত হতে পারি না তবে, আমি এখানে আছি, তালিকা <T> aList = নতুন তালিকা <T> (aFullListOfT) একটি গভীর অনুলিপি (যা আমি চাই) বা একটি অগভীর অনুলিপি (যা ভেঙে দেবে) তা আবিষ্কার করার চেষ্টা করছে আমার কোড) এবং কাজটি করার জন্য আমাকে অন্য কোনও পদ্ধতি বাস্তবায়ন করতে হবে কিনা!
— থান্ডারগ্রি

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

1
একটি তালিকা <T> আপনার লিখিত সামগ্রীগুলির সঠিকভাবে ক্লোনিং সম্পর্কে আরও কিছু জানতে পারে না। অন্তর্নিহিত অবজেক্টটি যদি পরিবর্তনযোগ্য না হয় তবে আপনি যেতে ভাল good অন্যথায়, অন্তর্নিহিত অবজেক্টের ক্লোন () পদ্ধতি থাকলে আপনাকে এটি ব্যবহার করতে হবে। তালিকা <T> aList = নতুন তালিকা <T> (aFullListOfT.Select (t = t.Clone ())
— ড্যানো

1
হাইব্রিড পদ্ধতির জন্য +1। উভয় পদ্ধতিরই একটি সুবিধা এবং অসুবিধা রয়েছে তবে এটি আরও সামগ্রিক উপকার বলে মনে হয়।
— কাইল বারান

12

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


5
@ গ্রান্ট, কনস্ট্রাক্টর রিলে কীভাবে ইচ্ছা করছে? আইওডাব্লু, যদি কোনও বস্তু কনস্ট্রাক্টরে নিজেকে নিয়ে যায় তবে অনুলিপিটি গভীর বা অগভীর? অন্যথায়, আমি ডিপকপি () (বা অন্যথায়) পরামর্শের সাথে সম্পূর্ণ সম্মত।
— মার্চ

7
আমি যুক্তি দিয়েছি যে একজন নির্মাতা আইসিএলনেবল ইন্টারফেসের মতো প্রায় অস্পষ্ট - আপনার এটিপি ডকস / কোড পড়তে হবে এটি একটি গভীর ক্লোন করে কিনা তা জানতে। আমি কেবল IDeepCloneable<T>একটি DeepClone()পদ্ধতির সাথে একটি ইন্টারফেস সংজ্ঞায়িত করি ।
— কেন্ট বুগার্ট

2
@ জন - চুল্লি শেষ হয়নি!
— গ্রান্ট ক্রফটন

@ মার্ক, @ কেন্ট - হ্যাঁ ফেয়ার পয়েন্ট, নির্মাতা সম্ভবত কোনও ভাল ধারণা নয়।
— গ্রান্ট ক্রফটন

3
কেউ কি এমন কোনও ব্যবহার দেখেছেন যেখানে অজানা প্রকারের কোনও জিনিসে আইক্লোনেবল ব্যবহার করা হয়েছিল? ইন্টারফেসের পুরো বিন্দুটি হ'ল এগুলি অজানা প্রকারের বস্তুগুলিতে ব্যবহার করা যেতে পারে; অন্যথায় কেউ কেবল ক্লোনকে একটি স্ট্যান্ডার্ড পদ্ধতিতে পরিণত করতে পারে যা প্রশ্নের ধরণটি দেয়।
— সুপারক্যাট

12

আপনি অনুলিপি নির্মাণকারী এবং বিমূর্ত ক্লাস নিয়ে সমস্যায় পড়বেন। আপনি নিম্নলিখিতটি করতে চান তা কল্পনা করুন:

abstract class A
{
    public A()
    {
    }

    public A(A ToCopy)
    {
        X = ToCopy.X;
    }
    public int X;
}

class B : A
{
    public B()
    {
    }

    public B(B ToCopy) : base(ToCopy)
    {
        Y = ToCopy.Y;
    }
    public int Y;
}

class C : A
{
    public C()
    {
    }

    public C(C ToCopy)
        : base(ToCopy)
    {
        Z = ToCopy.Z;
    }
    public int Z;
}

class Program
{
    static void Main(string[] args)
    {
        List<A> list = new List<A>();

        B b = new B();
        b.X = 1;
        b.Y = 2;
        list.Add(b);

        C c = new C();
        c.X = 3;
        c.Z = 4;
        list.Add(c);

        List<A> cloneList = new List<A>();

        //Won't work
        //foreach (A a in list)
        //    cloneList.Add(new A(a)); //Not this time batman!

        //Works, but is nasty for anything less contrived than this example.
        foreach (A a in list)
        {
            if(a is B)
                cloneList.Add(new B((B)a));
            if (a is C)
                cloneList.Add(new C((C)a));
        }
    }
}

উপরের কাজগুলি করার পরে, আপনি ইচ্ছে করা শুরু করেন আপনি হয় একটি ইন্টারফেস ব্যবহার করেছেন, অথবা ডিপকপি () / আইসিএলনেবল.ক্লোন () বাস্তবায়নের জন্য স্থির হয়েছেন।


2
একটি ইন্টারফেস-ভিত্তিক পদ্ধতির জন্য ভাল যুক্তি।
— ড্যানো

4

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

আমি এই বিষয়ে কোনও পরিষ্কার হতে একটি পাবলিক অনুলিপি নির্মাণকারী খুঁজে পাই না।

এটি বলেছিল, আমি এমন একটি পদ্ধতি সিস্টেম প্রবর্তন করব যা আপনার জন্য কাজ করে এবং রিলে অভিপ্রায় (ala কিছুটা স্ব-দস্তাবেজ)


3

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

আমার এখনই কোডটিতে অ্যাক্সেস নেই তবে এটি এরকম কিছু something

public object DeepCopy(object source)
{
   // Copy with Binary Serialization if the object supports it
   // If not try copying with XML Serialization
   // If not try copying with Data contract Serailizer, etc
}

6
গভীর ক্লোনিং বাস্তবায়নের মাধ্যম হিসাবে সিরিয়ালাইজেশনের ব্যবহার গভীর ক্লোনটিকে কর্টর বা পদ্ধতি হিসাবে প্রকাশ করা উচিত কিনা এই প্রশ্নের সাথে অপ্রাসঙ্গিক।
— কেন্ট বুগার্ট

1
আমি মনে করি এটি অন্য বৈধ বিকল্প। আমি ভাবি নি যে তিনি গভীর অনুলিপি করার এই দুটি পদ্ধতির মধ্যে সীমাবদ্ধ।
— শন বোউ

5
@ কেন্ট বুগার্ট - প্রদত্ত ওপিটি "সি # তে" একটি ক্লাসে অনুলিপি কার্যকারিতা যুক্ত করার গভীর উপায় "লাইন দিয়ে শুরু হয়েছে", আমি শনকে বিভিন্ন বিকল্প প্রস্তাব দেওয়ার পক্ষে এটি যথেষ্ট ন্যায্য বলে মনে করি। বিশেষত কোনও উত্তরাধিকারের দৃশ্যে যেখানে আপনার ক্লোন কার্যকারিতা কার্যকর করতে চান এমন বিশাল ক্লাস রয়েছে যেখানে এই কৌশলটি কার্যকর হতে পারে; সরাসরি আপনার নিজের ক্লোনটি বাস্তবায়নের মতো হালকা নয়, তবুও দরকারী useful যদি লোকেরা কখনই আমার প্রশ্নের বিকল্পগুলি "আপনি কি ভেবে দেখেছেন ..." না দিয়ে থাকেন তবে আমি বছরের পর বছরগুলি যতটা পেয়েছি প্রায় শিখতে পারিনি।
— রব লেভাইন

2

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

আমার থাকার জন্য:

// myobj is some transparent proxy object
var state = new ObjectState(myobj.State);

// do something

myobject = GetInstance();
var newState = new ObjectState(myobject.State);

if (!newState.Equals(state))
    throw new Exception();

পরিবর্তে:

// myobj is some transparent proxy object
var state = myobj.State.Clone();

// do something

myobject = GetInstance();
var newState = myobject.State.Clone();

if (!newState.Equals(state))
    throw new Exception();

অভিপ্রায় স্পষ্ট বিবৃতি হিসাবে দেখায়।


0

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

  1. যারা গভীর ক্লোনিংয়ের জন্য স্পষ্টভাবে সমর্থন করে
  2. যারা সদস্যপদে ক্লোনিংগুলি গভীর ক্লোনিং হিসাবে কাজ করবে তবে এগুলির সুস্পষ্ট সমর্থন বা প্রয়োজন নেই।
  3. যেগুলি দরকারীভাবে গভীরভাবে ক্লোন করা যায় না এবং যেখানে সদস্যপদযুক্ত ক্লোনিং করলে খারাপ ফল পাওয়া যায়।

আমি এখন পর্যন্ত বলতে পারি, বিদ্যমান অবজেক্ট হিসাবে একই শ্রেণির একটি নতুন অবজেক্ট পাওয়ার একমাত্র উপায় (অন্তত নেট নেট 2.0.০ এ) মেম্বারওয়াই ক্লোন ব্যবহার করা। একটি দুর্দান্ত প্যাটার্নটিতে "নতুন" / "শ্যাডো" ফাংশন ক্লোন থাকা বলে মনে হয় যা সর্বদা বর্তমান প্রকারটি দেয়, যার সংজ্ঞাটি সর্বদা মেম্বারওয়াই ক্লোনকে কল করে এবং তারপরে একটি সুরক্ষিত ভার্চুয়াল সাবরুটিন ক্লিনআপক্লোন (অরিজিনালজেক্ট) কল করে। ক্লিনআপকোড রুটিনটিতে বেস টাইপটির ক্লোনিংয়ের প্রয়োজনগুলি পরিচালনা করার জন্য বেস.ক্লিয়েনআপকোডটি কল করা উচিত এবং তারপরে নিজের ক্লিনআপ যুক্ত করুন। যদি ক্লোনিং রুটিনটি আসল অবজেক্টটি ব্যবহার করতে হয় তবে এটি টাইপকাস্ট হতে হবে তবে অন্যথায় কেবল টাইপকাস্টিংটি মেম্বারওয়াই ক্লোন কলটিতে থাকবে।

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

তবুও, আমি মনে করি একটি সংজ্ঞায়িত প্যাটার্ন থাকা কোনও কিছুর চেয়ে ভাল।

ঘটনাচক্রে, যদি কেউ জেনে থাকে যে কারও বেস টাইপটি আইক্লোনেবলকে সমর্থন করে তবে এটি যে ফাংশনটি ব্যবহার করে তার নামটি জানেন না, তবে তার বেস টাইপের আইক্লোনেবল.ক্লোন ফাংশনটি রেফারেন্স দেওয়ার কোনও উপায় আছে কি?


0

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

জেনেরিক এক্সটেনশন পদ্ধতিটি ব্যবহার করে আমি কীভাবে তৃতীয় পক্ষের শ্রেণীর বৈশিষ্ট্যগুলিকে "গভীরভাবে" ক্লোন করতে পারি?

এটি বর্ণনা করে যে কীভাবে একটি এক্সটেনশন পদ্ধতি প্রয়োগ করা যায় CreateCopy()যা সমস্ত সম্পত্তি সহ (কোনও সম্পত্তি দ্বারা সম্পত্তি দ্বারা অনুলিপি না করে) সহ সামগ্রীর "গভীর" অনুলিপি তৈরি করে।

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