سؤال

لنفترض لدي اثنين من الطبقات مع نفس واجهة:

interface ISomeInterface 
{
    int foo{get; set;}
    int bar{get; set;}
}

class SomeClass : ISomeInterface {}

class SomeOtherClass : ISomeInterface {}

لنفترض لدي مثيل ISomeInterface الذي يمثل SomeClass. هل هناك طريقة سهلة لنسخ ذلك في نسخة جديدة من SomeOtherClass دون نسخ كل عضو باليد؟

<القوي> UPDATE: بالنسبة للسجل، أنا <م> لا يحاول أن يلقي مثيل SomeClass إلى مثيل SomeOtherClass. ما أود القيام به هو شيء من هذا القبيل:

ISomeInterface sc = new SomeClass() as ISomeInterface;
SomeOtherClass soc = new SomeOtherClass();

soc.foo = sc.foo;
soc.bar = soc.bar;

وأنا لا أريد أن يكون للقيام بذلك لكل باليد لأن هذه الأشياء لديها الكثير من الخصائص.

هل كانت مفيدة؟

المحلول

و"؟ هل تكون قادرة على أن تعطيني مثالا على كيف تستطيع أن تفعل ذلك (أو على الأقل نقطة لي نحو الطرق الصحيحة لتكون استخدام) أنا لا يبدو أن تكون قادرة على العثور عليها على MSDN" - جايسون بيكر

وجيسون، شيء كما يلي:

var props = typeof(Foo)
            .GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo p in props)
{
     // p.Name gives name of property
}

وأنا أقترح كتابة أداة لبصق الرمز الذي تحتاجه للحصول على منشئ نسخة، بدلا من القيام بذلك في وقت التشغيل عاكس - التي ستكون أقل performant لل

نصائح أخرى

ويمكنك إنشاء شركات ضمنا في كل فئة للقيام التحويل لك:

public class SomeClass
{
    public static implicit operator SomeOtherClass(SomeClass sc)
    {
        //replace with whatever conversion logic is necessary
        return new SomeOtherClass()
        {
            foo = sc.foo,
            bar = sc.bar
        }
    }

    public static implicit operator SomeClass(SomeOtherClass soc)
    {
        return new SomeClass()
        {
            foo = soc.foo,
            bar = soc.bar
        }
    }
    //rest of class here
}

وثم SomeOtherClass soc = sc; والعكس بالعكس سوف تعمل.

وأليس وجهة واجهة ليكن لديك لتفعل ذلك؟ تفعل شيئا مع التنفيذ الفعلي للSomeOtherClass؟ بدلا من استخدام التنفيذ الملموس، استخدام واجهة ويجب أن لا يهم إذا كنت تستخدم SomeClass أو أساليب someother الصف.

وبخلاف ذلك، فإن أفضل ما يمكن أن تفعله هو أن يكتب نوعا من وظيفة مساعد (كنت لا تزال بحاجة الى القيام بذلك يدويا، أو النظر في التفكير) الذي نسخ كل خاصية على واجهة التي من شأنها أن تبدو مثل هذا:

   public ISomeInterface CopyValues(ISomeInterface fromSomeClass, ISomeInterface toSomeOtherClass)
   {
    //copy properties here
    return toSomeOtherClass;
    }

ولكن، أول غريزة بلدي سيكون القول الابتعاد عن تنفيذ والتركيز بدلا من ذلك باستخدام واجهة الخاص، فإنه لن يهم ما يكذب تحتها.

والتأمل ... حلقة من خلال كل الممتلكات، ووضعه على الممتلكات المقابلة على كائن آخر.

وراجع الجواب جو من أجل حل التأمل.

وأفترض أنك تستخدم Visual Studio.

هل أنت على دراية السيطرة تحول + + r و CTRL + SHIFT + ص اختصارات؟ إن لم يكن، السيطرة تحول + + ص يبدأ / ينتهي تسجيل ماكرو المفاتيح. CTRL + SHIFT + ص يلعب الماكرو المسجلة.

وماذا فعلت عندما أكون قد وضعت الكثير من الخصائص لنسخ الإعلانات الملكية إلى حيث أريد لها أن يتم تعيين وتسجيل ماكرو لتحور إعلان بيان مجموعة وتحريك المؤشر إلى السطر التالي فأنا مجرد اللعب حتى لقد جميع البيانات تعيين القيام به.

لا، لتحويل بشفافية (الزهر) كائن من نوع واحد إلى آخر، فئة محددة الكامنة وراء وجوه لديك، يجب أن ترث من فئة تحاول يطرح لل، حتى لو كانوا على حد سواء inplement نفسه واجهة.

ونفكر في ذلك، كل الكائنين يجب أن تكون مشتركة لتنفيذ نفس واجهة هو نفس فرعية من التوقيعات الأسلوب. قد لا (وربما لا) حتى يكون لها نفس الخصائص أو حقول البيانات.

ولن هذا العمل؟

class MyClass : ICloneable
{
public MyClass()
{

}
public object Clone() // ICloneable implementation
{
MyClass mc = this.MemberwiseClone() as MyClass;

return mc;
}

وأنت لا تملك إلا أن ندعو: MyClass.Clone ().

   ISomeInterface sc = new SomeClass() as ISomeInterface;
   SomeOtherClass soc = new SomeOtherClass();
   foreach (PropertyInfo info in typeof(ISomeInterface)
                                     .GetProperties(BindingFlags.Instance
                                                     |BindingFlags.Public))
   {
       info.SetValue(soc,info.GetValue(sc,null),null);
   }

وفعلت كما يلي، وأنه يعمل بشكل جيد جدا فقط لتحويل من كائن واحد في المشغل الضمني باستخدام آخر:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("hello");
            ExecutionReport er = new ExecutionReport("ORDID1234",3000.43,DateTime.UtcNow);
            Order ord = new Order();
            ord = er;
            Console.WriteLine("Transferred values are : " + er.OrderId + "\t" + ord.Amount.ToString() + "\t" + ord.TimeStamp.ToString() + "\t");
            Console.ReadLine();
        }
    }


    public  class Order
    {
        public string OrderId { get; set; }
        public double Amount { get; set; }
        public DateTime TimeStamp { get; set; }
        public static implicit operator ExecutionReport(Order ord)
        {
            return new ExecutionReport()
            {
                OrderId = ord.OrderId,
                Amount = ord.Amount,
                TimeStamp = ord.TimeStamp
            };
        }
        public static implicit operator Order(ExecutionReport er)
        {
            return new Order()
            {
                OrderId = er.OrderId,
                Amount = er.Amount,
                TimeStamp = er.TimeStamp
            };
        }

        public Order()
        { }
    }

    public  class ExecutionReport
    {
        public string OrderId { get; set; }
        public double Amount { get; set; }
        public DateTime TimeStamp { get; set; }
        public ExecutionReport() { }
        public ExecutionReport(string orderId,double amount, DateTime ts)
        {
            OrderId = orderId; Amount = amount; TimeStamp = ts;
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top