سؤال
أريد استنساخ كائن باستخدام ICloneable
واجهة ولسبب ما لا أستطيع استنساخ في برنامجي. ها هو رمزتي:
public class GeoInfo : ICloneable
{
private long InfoID;
private string InfoName;
private Location InfoLocation;
private string Description;
private InfoTypes InfoType;
public GeoInfo(long InfoID)
{
this.InfoID = InfoID;
}
public GeoInfo(long InfoID, Location InfoLocation):this(InfoID)
{
this.InfoLocation = InfoLocation;
}
public GeoInfo(long InfoID, string InfoName, Location InfoLocation, string Description, InfoTypes InfoType):this(InfoID,InfoLocation)
{
this.InfoName = InfoName;
this.Description = Description;
this.InfoType = InfoType;
}
public object ICloneable.Clone()
{
GeoInfo toReturn = new GeoInfo(InfoID, InfoName, InfoLocation, Description, InfoType);
return (object)toReturn;
}
}
داخل فصل آخر عندما أحاول استخدام Clone()
الطريقة ، لسبب ما ، لا يمكن للمترجم العثور على الطريقة. هذه هي طريقتي الأخرى التي تحاول استنساخ:
public InfoLayer(string LayerName,List<GeoInfo> oldGeoInfos)
{
this.LayerName = LayerName;
this.GeoInfos = new List<GeoInfo>();
oldGeoInfos.ForEach((item) =>
{
GeoInfos.Add((GeoInfo)((ICloneable)item.Clone()));
});
}
المحلول
الأقواس حول الممثلين الخاص بك ليست صحيحة. يجب أن تقرأ
GeoInfos.Add((GeoInfo)((ICloneable)item).Clone());
(بالمناسبة: لماذا. foreach ()؟
this.GeoInfos = oldGeoInfos.Select(item => ((GeoInfo)((ICloneable)item.Clone()))).ToList();
هل الوظيفة كذلك.)
نصائح أخرى
كما قال آخرون إنك قمت بتنفيذ الواجهة بشكل صريح. ما أفعله هو إنشاء طريقة أخرى تُرجع إصدارًا من Typesafe من طريقة الاستنساخ ، لذا أميل إلى تضمينه.
public GeoInfo Clone()
{
return new GeoInfo(InfoID, InfoName, InfoLocation, Description, InfoType);
}
وتغيير طريقة الاستنساخ التي تم تنفيذها (يجب إزالة المعدل العام) ...
object ICloneable.Clone()
{
return Clone(); //will call the public method as above
}
وبهذه الطريقة ، ليس عليك أن تلقي من كائن إلى النوع الحقيقي.
ومع ذلك ، هناك عدد من الصعوبات مع iClonable:
- أنت لا تعرف ما إذا كان يجب أن يكون الاستنساخ استنساخ عميق أو ضحل
- يجب عليك توفير آلية للدروس المشتقة لاستنساخ نفسها والتي يمكنك القيام بها عبر الأساليب الافتراضية. أميل إلى إغلاق فصولي في الحالات ، لا يمكنني ضمان الاستنساخ المناسب في أنواع مشتقة ، لكن هذا قرار يجب اتخاذه على أساس الأرشفة واحتياجاتك.
يجب عليك الاتصال فقط طريقتك
public object Clone()
يحرر:
أو اتصل بطريقتك
oldGeoInfos.ForEach((item) =>
{
GeoInfos.Add((GeoInfo)(((ICloneable)item).Clone()));
});
لاحظ إضافي ()
.
يجب أن يقرأ الخط
GeoInfos.Add((GeoInfo)((ICloneable)item).Clone());
لكن ضع في اعتبارك في GeoInfo
الفصل لعدم استخدام تنفيذ الواجهة الصريحة (يجب عدم تجميع مثالك على أي حال) ، بحيث يقرأ:
public object Clone()
{
//...
}
ثم يمكنك ببساطة القيام به
GeoInfos.Add((GeoInfo)item.Clone());
لقد نفذت ICloneable.Clone
صراحة ، الأمر الذي يتطلب إلقاء الكائن إليه ICloneable
قبل أن يتم استدعاء Method Cane.
نرى تنفيذ الواجهة الصريحة على MSDN.
إذا كنت ترغب في الاتصال بالطريقة على كائنك ، فقم بتغيير إعلان الطريقة إلى:
public object Clone()
بدلاً من ذلك ، إذا كنت ترغب في الحفاظ على فحص النوع الثابت ، اترك تطبيقك الحالي كما هو ، وأضف ما يلي:
public GeoInfo Clone()
{
return ((ICloneable)this).Clone();
}