سؤال

أريد استنساخ كائن باستخدام 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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top