জেনেরিকের ICloneable<T>
অস্তিত্ব না থাকার কোনও কারণ আছে কি ?
এটি অনেক বেশি স্বাচ্ছন্দ্যযুক্ত হবে, যদি প্রতিবার আমি কিছু ক্লোন করে ফেলার প্রয়োজন হয় না।
জেনেরিকের ICloneable<T>
অস্তিত্ব না থাকার কোনও কারণ আছে কি ?
এটি অনেক বেশি স্বাচ্ছন্দ্যযুক্ত হবে, যদি প্রতিবার আমি কিছু ক্লোন করে ফেলার প্রয়োজন হয় না।
উত্তর:
আইসিএলনেবলকে এখন একটি খারাপ এপিআই হিসাবে বিবেচনা করা হচ্ছে, কারণ ফলাফলটি গভীর বা অগভীর অনুলিপি কিনা তা নির্দিষ্ট করে না। আমি মনে করি এই কারণেই তারা এই ইন্টারফেসটির উন্নতি করে না।
আপনি সম্ভবত একটি টাইপযুক্ত ক্লোনিং এক্সটেনশন পদ্ধতি করতে পারেন তবে আমার মনে হয় এটির জন্য একটি আলাদা নামের প্রয়োজন কারণ এক্সটেনশন পদ্ধতির মূলগুলির চেয়ে কম অগ্রাধিকার রয়েছে।
List<T>
কোনও ক্লোন পদ্ধতি থাকে তবে আমি এটি প্রত্যাশা করবো List<T>
যেগুলির আইটেমগুলির মূল তালিকার মতো একই পরিচয় রয়েছে তবে আমি আশা করব যে কোনও তালিকার কোনও কিছুই প্রভাবিত হবে না তা নিশ্চিত করার জন্য যে কোনও অভ্যন্তরীণ ডেটা স্ট্রাকচারগুলি নকল করা হবে ensure পরিচয় আইটেম অন্য সংরক্ষণ করা হয়। অস্পষ্টতা কোথায়? ক্লোনিংয়ের একটি বড় সমস্যা "হীরা সমস্যা" এর পরিবর্তনের সাথে আসে: যদি CloneableFoo
[সর্বজনীনভাবে ক্লোনযোগ্য নয়] থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় তবে তা থেকে প্রাপ্ত Foo
হওয়া উচিত CloneableDerivedFoo
...
identity
তালিকার একটিতে কী বিবেচনা করবেন , উদাহরণস্বরূপ (তালিকার তালিকার ক্ষেত্রে)? যাইহোক, যে উপেক্ষা, আপনার প্রত্যাশা না শুধুমাত্র সম্ভব ধারণা মানুষ যখন কল করা বা বাস্তবায়ন আছে পারে Clone
। যদি অন্য কিছু তালিকা বাস্তবায়ন করে গ্রন্থাগারের লেখকরা আপনার প্রত্যাশা অনুসরণ না করে তবে কী হবে? এপিআইটি তুচ্ছভাবে দ্ব্যর্থহীন হওয়া উচিত, তর্কাতীতভাবে দ্ব্যর্থহীন নয়।
Clone
তার সমস্ত অংশগুলিতে কল করে, এটি পূর্বাভাসের সাথে কাজ করবে না - সেই অংশটি আপনার বা সেই ব্যক্তি দ্বারা প্রয়োগ করা হয়েছিল কিনা তার উপর নির্ভর করে যারা গভীর ক্লোনিং পছন্দ করেন। নিদর্শনগুলি সম্পর্কে আপনার বক্তব্য বৈধ তবে এপিআই-তে আইএমএইচএও থাকা যথেষ্ট স্পষ্ট নয় - এটি হয় ShallowCopy
বিন্দুকে চাপ দেওয়ার জন্য বলা উচিত , বা আদৌ সরবরাহ করা হয়নি।
আন্দ্রে উত্তর ছাড়াও (যা আমি একমত +1) - যখন ICloneable
হয় কাজ, এছাড়াও আপনি স্পষ্ট বাস্তবায়ন পাবলিক করা চয়ন করতে পারেন Clone()
আগমন একটি টাইপ বস্তু:
public Foo Clone() { /* your code */ }
object ICloneable.Clone() {return Clone();}
অবশ্যই জেনেরিক ICloneable<T>
- উত্তরাধিকার নিয়ে দ্বিতীয় সমস্যা রয়েছে ।
যদি আমার থাকে:
public class Foo {}
public class Bar : Foo {}
এবং আমি বাস্তবায়ন করেছি ICloneable<T>
, তাহলে আমি কি বাস্তবায়ন করব ICloneable<Foo>
? ICloneable<Bar>
? আপনি দ্রুত প্রচুর অভিন্ন ইন্টারফেস প্রয়োগ করতে শুরু করেছেন ... একটি কাস্টের সাথে তুলনা করুন ... এবং এটি কি এত খারাপ?
আমার জিজ্ঞাসা করা দরকার, আপনি ইন্টারফেসটি বাস্তবায়ন ছাড়া অন্যটি দিয়ে ঠিক কী করবেন ? ইন্টারফেসগুলি কেবল তখনই কার্যকর হয় যখন আপনি এটিতে কাস্ট করেন (যেমন এই শ্রেণিটি 'আইবার' সমর্থন করে), বা প্যারামিটার বা সেটারগুলি রয়েছে যা এটি গ্রহণ করে (যেমন আমি একটি 'আইবার' নিই)। আইসিএলনেবলের সাথে - আমরা পুরো ফ্রেমওয়ার্কটি পেরিয়ে গিয়েছিলাম এবং এটির প্রয়োগ ব্যতীত অন্য কোনও কিছু ছিল এমন একক ব্যবহার সন্ধান করতে ব্যর্থ হয়েছি। আমরা 'বাস্তব বিশ্বে' এমন কোনও ব্যবহার সন্ধান করতেও ব্যর্থ হয়েছি যা এটিকে বাস্তবায়ন করা ছাড়াও অন্য কিছু করে (আমাদের যে ~ 60,000 অ্যাপ্লিকেশনটিতে অ্যাক্সেস রয়েছে)।
এখন আপনি যদি এমন একটি প্যাটার্ন প্রয়োগ করতে চান যা আপনি নিজের 'ক্লোনযোগ্য' অবজেক্টগুলি প্রয়োগ করতে চান তবে এটি সম্পূর্ণ সূক্ষ্ম ব্যবহার - এবং এগিয়ে যান। আপনার কাছে "ক্লোনিং" এর অর্থ কী (যেমন গভীর বা অগভীর) ঠিক তাও আপনি সিদ্ধান্ত নিতে পারেন। তবে সেক্ষেত্রে আমাদের (বিসিএল) এটি সংজ্ঞায়িত করার দরকার নেই। আমরা কেবলমাত্র ছাত্রলীগে বিমূর্ততাগুলি সংজ্ঞায়িত করি যখন কোনও সম্পর্কযুক্ত লাইব্রেরির মধ্যে বিমূর্ততা হিসাবে টাইপ করা উদাহরণগুলি বিনিময় করার প্রয়োজন হয়।
ডেভিড কেন (বিসিএল দল)
ICloneable<out T>
বেশ উপযোগী হতে পারে যদি তা থেকে উত্তরাধিকারসূত্রে ISelf<out T>
একটি একক পদ্ধতি সঙ্গে, Self
ধরনের T
। একজনের প্রায়শই "ক্লোনযোগ্য এমন কিছু" প্রয়োজন হয় না তবে ক্লোনযোগ্য এমন একটির খুব প্রয়োজন হতে পারে T
। যদি কোনও ক্লোনযোগ্য অবজেক্ট প্রয়োগ করে ISelf<itsOwnType>
, এমন একটি রুটিন যা T
ক্লোনযোগ্য দরকার তার ধরণের একটি পরামিতি গ্রহণ করতে পারে ICloneable<T>
, এমনকি যদি ক্লোনিয়েবল ডেরিভেটিভসগুলি T
একটি সাধারণ পূর্বপুরুষের ভাগ না করে।
ICloneable<T>
জন্য কার্যকর হতে পারে, যদিও সমান্তরাল পরিবর্তনযোগ্য এবং অপরিবর্তনীয় শ্রেণি বজায় রাখার জন্য বিস্তৃত কাঠামো আরও সহায়ক হতে পারে। অন্য কথায়, কোড যা কোন ধরণের কী Foo
রয়েছে তা দেখার প্রয়োজন কিন্তু এটির রূপান্তর করতে পারে না বা আশাও করে না যে এটি কখনও পরিবর্তিত হবে না IReadableFoo
, যখন ...
Foo
একটি ব্যবহার করতে পারে ImmutableFoo
নিপূণভাবে এটি একটি ব্যবহার করতে পারে চায় যে যখন কোড MutableFoo
। যে কোনও ধরণের কোড দেওয়া IReadableFoo
কোডগুলি কোনও পরিবর্তনীয় বা অপরিবর্তনীয় সংস্করণ পেতে সক্ষম হওয়া উচিত। এই জাতীয় কাঠামো সুন্দর হবে তবে দুর্ভাগ্যক্রমে আমি জেনেরিক ফ্যাশনে জিনিস সেট আপ করার কোনও দুর্দান্ত উপায় খুঁজে পাচ্ছি না। কোনও শ্রেণীর জন্য কেবল পঠনযোগ্য মোড়ক তৈরির জন্য যদি ধারাবাহিক উপায় থাকে তবে এই জাতীয় জিনিসটি ICloneable<T>
একটি শ্রেণীর একটি অনিবার্য অনুলিপি তৈরির সাথে মিশ্রণে ব্যবহার করা যেতে পারে T
।
List<T>
, যেমন ক্লোনন List<T>
হ'ল একটি নতুন সংগ্রহ যা মূল সংগ্রহের একই সামগ্রীর সকলের জন্য পয়েন্টার রাখে, তা ছাড়া এটি করার দুটি সহজ উপায় রয়েছে ICloneable<T>
। প্রথমটি হল Enumerable.ToList()
এক্সটেনশন পদ্ধতি: List<foo> clone = original.ToList();
দ্বিতীয়টি List<T>
নির্মাণকারী যা গ্রহণ করে IEnumerable<T>
: List<foo> clone = new List<foo>(original);
আমার সন্দেহ হয় যে এক্সটেনশন পদ্ধতিটি সম্ভবত কেবল কনস্ট্রাক্টরকে কল করছে, তবে এই উভয়ই আপনি যা অনুরোধ করছেন তা করবে। ;)
আমি মনে করি "কেন" প্রশ্নটি অপ্রয়োজনীয়। এখানে অনেকগুলি ইন্টারফেস / ক্লাস / ইত্যাদি রয়েছে ... যা খুব দরকারী, তবে। নেট ফ্রেমওয়ার্কু বেস লাইব্রেরির অংশ নয়।
তবে, প্রধানত আপনি নিজেরাই এটি করতে পারেন।
public interface ICloneable<T> : ICloneable {
new T Clone();
}
public abstract class CloneableBase<T> : ICloneable<T> where T : CloneableBase<T> {
public abstract T Clone();
object ICloneable.Clone() { return this.Clone(); }
}
public abstract class CloneableExBase<T> : CloneableBase<T> where T : CloneableExBase<T> {
protected abstract T CreateClone();
protected abstract void FillClone( T clone );
public override T Clone() {
T clone = this.CreateClone();
if ( object.ReferenceEquals( clone, null ) ) { throw new NullReferenceException( "Clone was not created." ); }
return clone
}
}
public abstract class PersonBase<T> : CloneableExBase<T> where T : PersonBase<T> {
public string Name { get; set; }
protected override void FillClone( T clone ) {
clone.Name = this.Name;
}
}
public sealed class Person : PersonBase<Person> {
protected override Person CreateClone() { return new Person(); }
}
public abstract class EmployeeBase<T> : PersonBase<T> where T : EmployeeBase<T> {
public string Department { get; set; }
protected override void FillClone( T clone ) {
base.FillClone( clone );
clone.Department = this.Department;
}
}
public sealed class Employee : EmployeeBase<Employee> {
protected override Employee CreateClone() { return new Employee(); }
}
ইন্টারফেসটি প্রয়োজন হলে নিজেই লেখা খুব সহজ :
public interface ICloneable<T> : ICloneable
where T : ICloneable<T>
{
new T Clone();
}
সাম্প্রতিক নিবন্ধটি পড়ে কেন কোনও বস্তুর অনুলিপি করা একটি ভয়ঙ্কর কাজ? , আমি মনে করি এই প্রশ্নের অতিরিক্ত স্পেসিফিকেশন দরকার। এখানে অন্যান্য উত্তরগুলি ভাল পরামর্শ সরবরাহ করে, তবে এখনও উত্তরটি সম্পূর্ণ হয় না - কেন নয় ICloneable<T>
?
ব্যবহার
সুতরাং, আপনার একটি ক্লাস রয়েছে যা এটি প্রয়োগ করে। পূর্বে আপনার কাছে এমন পদ্ধতি ছিল যা চেয়েছিল তবে ICloneable
এটি এখন গ্রহণযোগ্য হতে হবে ICloneable<T>
। আপনার এটি সম্পাদনা করতে হবে।
তারপরে, আপনি একটি পদ্ধতি পেতে পারেন যা চেক করে কোনও বস্তু কিনা is ICloneable
। এখন কি? আপনি করতে পারবেন না is ICloneable<>
এবং যেহেতু আপনি কম্পাইল-টাইপে অবজেক্টের ধরণ জানেন না, আপনি পদ্ধতিটিকে জেনেরিক করতে পারবেন না। প্রথম আসল সমস্যা।
সুতরাং আপনার উভয় ICloneable<T>
এবং ICloneable
পূর্ববর্তী পরবর্তী প্রয়োগকারী থাকা দরকার। সুতরাং একজন প্রয়োগকারীকে উভয় পদ্ধতি প্রয়োগ করতে হবে - object Clone()
এবং T Clone()
। না, ধন্যবাদ, ইতিমধ্যে আমরা যথেষ্ট মজা পেয়েছি IEnumerable
।
ইতিমধ্যে চিহ্নিত হিসাবে, উত্তরাধিকার জটিলতাও রয়েছে। যদিও সমগোত্রীয়তা এই সমস্যার সমাধান করতে পারে বলে মনে হয়, একটি উদ্ভূত প্রকারের ICloneable<T>
নিজস্ব ধরণের প্রয়োগ করতে হবে তবে ইতিমধ্যে একই স্বাক্ষরযুক্ত একটি পদ্ধতি রয়েছে (= পরামিতি, মূলত) - Clone()
বেস শ্রেণীর। আপনার নতুন ক্লোন পদ্ধতির ইন্টারফেসটি সুস্পষ্ট করা অর্থহীন, আপনি তৈরি করার সময় আপনি যে সুবিধাটি চেয়েছিলেন তা হারাবেন ICloneable<T>
। সুতরাং new
কীওয়ার্ডটি যুক্ত করুন । তবে ভুলে যাবেন না যে আপনাকে বেস ক্লাসটি ওভাররাইড করা দরকার ' Clone()
(বাস্তবায়নের জন্য সমস্ত উত্পন্ন শ্রেণীর জন্য অভিন্ন থাকতে হবে, অর্থাত্ প্রতিটি ক্লোন পদ্ধতি থেকে একই জিনিসটি ফিরে আসতে হবে, তাই বেস ক্লোন পদ্ধতিটিই হতে হবে virtual
)! তবে, দুর্ভাগ্যক্রমে, আপনি override
এবং উভয়ই পারেন নাnew
একই স্বাক্ষর সহ পদ্ধতি। প্রথম কীওয়ার্ডটি নির্বাচন করা, আপনি যুক্ত করার সময় আপনার যে লক্ষ্যটি চেয়েছিল তা হারাবেন ICloneable<T>
। দ্বিতীয়টি বেছে নেওয়া, আপনি নিজেই ইন্টারফেসটি ভেঙে ফেলবেন, এমন পদ্ধতি তৈরি করে যাতে একই জিনিসটি বিভিন্ন বস্তুতে ফিরে আসে।
বিন্দু
আপনি ICloneable<T>
স্বাচ্ছন্দ্যের জন্য চান , তবে স্বাচ্ছন্দ্যের জন্য ইন্টারফেসগুলি কীভাবে ডিজাইন করা হয়েছে তা নয়, এর অর্থ (সাধারণ ওওপিতে) অবজেক্টগুলির আচরণকে একত্রিত করার জন্য (যদিও সি # তে, এটি বাহ্যিক আচরণকে একত্রিত করার ক্ষেত্রে সীমাবদ্ধ, যেমন পদ্ধতি এবং বৈশিষ্ট্যগুলি নয়, তাদের কাজ)।
যদি প্রথম কারণটি আপনাকে এখনও নিশ্চিত করে না, আপনি ICloneable<T>
ক্লোন পদ্ধতি থেকে ফিরে আসা টাইপটিকে সীমাবদ্ধ করতে, এটি নিষিদ্ধভাবে কাজ করতে পারে এমন আপত্তিও করতে পারেন। তবে, দুষ্টু প্রোগ্রামার প্রয়োগ করতে পারে ICloneable<T>
যেখানে টি প্রকারটি প্রয়োগ করে না। সুতরাং, আপনার সীমাবদ্ধতা অর্জনের জন্য, আপনি জেনেরিক প্যারামিটারে একটি দুর্দান্ত প্রতিবন্ধকতা যুক্ত করতে পারেন:
public interface ICloneable<T> : ICloneable where T : ICloneable<T>
নিশ্চিতভাবেই আরও বিধিনিষেধ ব্যতীত where
, আপনি এখনও সীমাবদ্ধ করতে পারবেন না যে টি ইন্টারফেসটি কার্যকর করছে এমন ধরণটি (আপনি ICloneable<T>
বিভিন্ন ধরণের থেকে প্রাপ্ত করতে পারেন) এটি প্রয়োগ করে)।
আপনি দেখুন, এমনকি এই উদ্দেশ্য অর্জন করা যায়নি (আসলটিও ICloneable
এতে ব্যর্থ হয়, কোনও ইন্টারফেস বাস্তবায়িত শ্রেণীর আচরণকে সীমাবদ্ধ করতে পারে না)।
আপনি দেখতে পাচ্ছেন যে, জেনেরিক ইন্টারফেসটিকে পুরোপুরি বাস্তবায়ন করা শক্ত এবং সত্যই অপ্রয়োজনীয় এবং অকেজো উভয়ই প্রমাণ করে।
তবে এই প্রশ্নটির দিকে ফিরে, আপনি কোন বিষয়টির ক্লোনিং করার সময় আরাম পাওয়া really এটি করার দুটি উপায় রয়েছে:
public class Base : ICloneable
{
public Base Clone()
{
return this.CloneImpl() as Base;
}
object ICloneable.Clone()
{
return this.CloneImpl();
}
protected virtual object CloneImpl()
{
return new Base();
}
}
public class Derived : Base
{
public new Derived Clone()
{
return this.CloneImpl() as Derived;
}
protected override object CloneImpl()
{
return new Derived();
}
}
এই সমাধানটি ব্যবহারকারীদের স্বাচ্ছন্দ্য এবং উদ্দেশ্যমূলক আচরণ উভয়ই সরবরাহ করে তবে এটি বাস্তবায়নের জন্যও এটি অনেক দীর্ঘ। যদি আমরা বর্তমানের ধরণটি ফিরিয়ে আনতে "আরামদায়ক" পদ্ধতিটি না নিতে চাই, তবে এটি ঠিক থাকা আরও অনেক সহজ public virtual object Clone()
।
তাহলে আসুন "চূড়ান্ত" সমাধানটি দেখুন - সি # তে আসলে কী আমাদের সান্ত্বনা দেওয়ার জন্য উদ্দিষ্ট?
public class Base : ICloneable
{
public virtual object Clone()
{
return new Base();
}
}
public class Derived : Base
{
public override object Clone()
{
return new Derived();
}
}
public static T Copy<T>(this T obj) where T : class, ICloneable
{
return obj.Clone() as T;
}
এটা তোলে নামে এর অনুলিপি বর্তমান সঙ্গে ধাক্কা লাগা না ক্লোন পদ্ধতি (কম্পাইলার এক্সটেনশন বেশী বেশী টাইপ নিজস্ব ঘোষিত পদ্ধতি পছন্দ করে)। class
বাধ্যতা সেখানে গতির জন্য (পরীক্ষা নাল ইত্যাদি প্রয়োজন হয় না) হয়।
আমি আশা করি এটি কারণ না করার কারণ স্পষ্ট করে দেয় ICloneable<T>
। তবে এটিকে বাস্তবায়ন না করার পরামর্শ দেওয়া হচ্ছে ICloneable
।
ICloneable
মান ধরণের জন্য, যেখানে এটি ক্লোন পদ্ধতির বক্সিংটি বাধা দিতে পারে, এবং এটি ইঙ্গিত দেয় যে আপনার মানটি বাক্সবাক্সিত নয়। এবং কাঠামোগুলি স্বয়ংক্রিয়ভাবে ক্লোন করা যেতে পারে (অগভীরভাবে) তাই এটি কার্যকর করার দরকার নেই (যদি আপনি এটি নির্দিষ্ট করে না যে এটি গভীর অনুলিপি বোঝায়)।
যদিও প্রশ্নটি খুব পুরানো (এই উত্তরগুলি লেখার 5 বছর :) :) এবং ইতিমধ্যে উত্তর দেওয়া হয়েছিল, তবে আমি এই নিবন্ধটি প্রশ্নের উত্তরটি বেশ ভালভাবে পেয়েছি, এটি এখানে দেখুন
সম্পাদনা করুন:
নিবন্ধটির উদ্ধৃতিটি এখানে প্রশ্নের উত্তর দিয়েছে (পুরো নিবন্ধটি পড়ার বিষয়টি নিশ্চিত করুন, এতে অন্যান্য আকর্ষণীয় বিষয় রয়েছে):
মাইক্রোসফ্টে নিযুক্ত সময়ে - ব্র্যাড আব্রামস দ্বারা 2003 সালে একটি ব্লগ পোস্টের দিকে ইঙ্গিত করে ইন্টারনেটে অনেকগুলি উল্লেখ রয়েছে - এতে আইক্লোনেবল সম্পর্কে কিছু চিন্তাভাবনা আলোচনা করা হয়েছে। ব্লগ এন্ট্রি এই ঠিকানায় পাওয়া যাবে: ICloneable বাস্তবায়ন । বিভ্রান্তকারী শিরোনাম সত্ত্বেও, এই ব্লগ এন্ট্রিটি মূলত অগভীর / গভীর বিভ্রান্তির কারণে ICloneable প্রয়োগ না করার আহ্বান জানায়। নিবন্ধটি একটি সরাসরি পরামর্শে শেষ হয়: আপনার যদি ক্লোনিং প্রক্রিয়া দরকার হয়, আপনার নিজের ক্লোন বা কপি পদ্ধতিটি সংজ্ঞায়িত করুন এবং নিশ্চিত করুন যে আপনি এটি গভীর বা অগভীর অনুলিপি কিনা তা স্পষ্টভাবে নথিভুক্ত করেছেন। একটি উপযুক্ত প্যাটার্ন হ'ল:
public <type> Copy();
একটি বড় সমস্যা হ'ল তারা টি একই শ্রেণি হতে সীমাবদ্ধ করতে পারেনি। উদাহরণস্বরূপ যা আপনাকে এটি করতে বাধা দিতে পারে:
interface IClonable<T>
{
T Clone();
}
class Dog : IClonable<JackRabbit>
{
//not what you would expect, but possible
JackRabbit Clone()
{
return new JackRabbit();
}
}
তাদের যেমন প্যারামিটার সীমাবদ্ধতা প্রয়োজন:
interfact IClonable<T> where T : implementing_type
class A : ICloneable { public object Clone() { return 1; } /* I can return whatever I want */ }
ICloneable<T>
যেতে বাধা সৃষ্টি T
করতে পারে , তবে Clone()
এটি ক্লোন করা বস্তুর সাথে সাদৃশ্যপূর্ণ কিছু প্রত্যাবর্তন করতে কোনও প্রয়োগকে বাধ্য করবে না । আরও, আমি প্রস্তাব দিচ্ছি যে যদি কেউ ইন্টারফেস covariance ব্যবহার করে থাকে তবে ক্লাসগুলি প্রয়োগ ICloneable
করা সিল করা ভাল হতে পারে , ইন্টারফেসটিতে ICloneable<out T>
এমন একটি Self
সম্পত্তির অন্তর্ভুক্ত থাকতে হবে যা প্রত্যাশিত নিজেই ফিরে আসে, এবং ...
ICloneable<BaseType>
বা ICloneable<ICloneable<BaseType>>
। BaseType
প্রশ্নে একটি থাকতে হবে protected
ক্লোনিং জন্য পদ্ধতি, যা টাইপ যা কার্যকরী ডাকা হবে ICloneable
। এই নকশাটি এমন একটি সম্ভাবনার পক্ষে অনুমতি দেবে যে কেউ একটি Container
, ক CloneableContainer
, ক FancyContainer
এবং CloneableFancyContainer
ক এর উত্তরোত্তর ব্যবহার করতে পারে যার ক্লোনযোগ্য ডেরাইভেটিভ Container
প্রয়োজন হয় বা যার প্রয়োজন হয় FancyContainer
(তবে এটি ক্লোনযোগ্য কিনা সেদিকে খেয়াল রাখে না)।
FancyList
কারওর কাছে এমন একটি প্রকার থাকতে পারে যা সংবেদনশীলভাবে ক্লোন করা যেতে পারে, তবে একটি ডেরাইভেটিভ স্বয়ংক্রিয়ভাবে ডিস্ক ফাইলে (কনস্ট্রাক্টরের নির্দিষ্ট করা) নিজের অবস্থান স্থির রাখতে পারে। উদ্ভূত প্রকারটি ক্লোন করা যায়নি, কারণ এর রাজ্যটি একটি পরিবর্তনীয় সিঙ্গলটন (ফাইল) এর সাথে সংযুক্ত করা হবে, তবে এটি এমন জায়গায় ডাইরাইপড প্রকারের ব্যবহারকে বিরত রাখতে পারে না যেখানে বেশিরভাগ বৈশিষ্ট্যের প্রয়োজন হয় FancyList
তবে প্রয়োজন হয় না এটি ক্লোন করতে
এটি একটি খুব ভাল প্রশ্ন ... আপনি নিজের তৈরি করতে পারেন, যদিও:
interface ICloneable<T> : ICloneable
{
new T Clone ( );
}
আন্দ্রে বলছেন এটিকে একটি খারাপ এপিআই হিসাবে বিবেচনা করা হয়েছে, তবে আমি এই ইন্টারফেসটিকে হ্রাস করা সম্পর্কে কিছুই শুনিনি। এবং এটি বহু সংখ্যক ইন্টারফেস ভঙ্গ করবে ... ক্লোন পদ্ধতিটি একটি অগভীর অনুলিপি সম্পাদন করা উচিত। যদি বস্তুটি গভীর অনুলিপি সরবরাহ করে তবে একটি ওভারলোডেড ক্লোন (বুল গভীর) ব্যবহার করা যেতে পারে।
সম্পাদনা: প্যাটার্ন আমি কোনও বস্তুর "ক্লোনিং" করার জন্য ব্যবহার করি, কনস্ট্রাক্টরের মধ্যে একটি প্রোটোটাইপ পাস করে।
class C
{
public C ( C prototype )
{
...
}
}
এটি কোনও সম্ভাব্য অপ্রয়োজনীয় কোড প্রয়োগের পরিস্থিতি সরিয়ে দেয়। বিটিডাব্লু, আইসিএলনেবলের সীমাবদ্ধতা সম্পর্কে কথা বলার পরে, কোনও অগভীর ক্লোন বা গভীর ক্লোন, বা এমনকি আংশিক অগভীর / আংশিক গভীর ক্লোনটি সম্পাদন করা উচিত কিনা তা নিজেই ঠিক সিদ্ধান্ত নেওয়া উচিত নয়? যতক্ষণ না উদ্দেশ্য হিসাবে কাজ করা উচিত ততক্ষণ আমাদের কি যত্ন নেওয়া উচিত? কিছু ক্ষেত্রে, একটি ভাল ক্লোন প্রয়োগের ক্ষেত্রে খুব ভালভাবে অগভীর এবং গভীর ক্লোনিং উভয়ই অন্তর্ভুক্ত থাকতে পারে।