سؤال

وأنا ترينغ لبناء مكتبة للsimplifing المكالمات ملزمة في وقت متأخر من C #، وأنا اتلقى مشكلة ترينغ مع parameteres المرجعية. لدي الطريقة التالية لإضافة المعلمة المستخدمة في استدعاء أسلوب

    public IInvoker AddParameter(ref object value)
    {
        //List<object> _parameters = new List<object>();
        _parameters.Add(value);          

        //List<bool> _isRef = new List<bool>();
        _isRef.Add(true);

        return this;
    }

والتي لا تعمل مع أنواع قيمة، لأنها تحصل على محاصر ككائن، وبالتالي لا يتم تعديلها. منها مثلا:

int param1 = 2;
object paramObj = param1;
//MulFiveRef method multiplies the integer passed as a reference parameter by 5:
//void MulFiveRef(ref int value) { value *= 5; }
fi.Method("MulFiveRef").AddParameter(ref paramObj);

وهذا لا يعمل. الدعوة ملزمة أواخر ناجحة، والقائمة الداخلية التي تتولى parameteres (_parameters) لا يحصل تعديل، ولكن لا قيمة خارج المكالمة.

لا أحد يعرف طريقة بسيطة للتغلب على هذا القيد؟ التوقيع AddParameter لا يمكن تعديلها، كما هو الحال مع المكالمات ملزمة في وقت متأخر، لا يمكنك معرفة مقدما نوع من المعلمات (وإما طريق إدراج جميع المعلمات لاستدعاء داخل مجموعة الكائن قبل إجراء المكالمة)

وشكرا مقدما.

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

المحلول

وإذا كانت قيمة يتغير <م> داخل طريقة ، سوف تحتاج إلى تعريف متغير مؤقت (object) لتمرير (ref) إلى أسلوب، وخدمة Unbox ذلك بنفسك بعد ذلك:

    int i = 3;
    //...
    object obj = i;
    Foo(ref obj);
    i = (int)obj;

لاحظ أن هذا لن تسمح لك بتحديث قيمة بعد وقوع الحدث. شيء من هذا القبيل حدث أو الاستدعاء قد تكون وسيلة بديلة لتمرير التغييرات مرة أخرى إلى الطالب.

ملحوظة أيضا أن C # 4.0 لديه بعض الحيل للمساعدة في هذا <م> فقط في سياق COM يدعو (حيث ref object هو شائع جدا [بالإضافة بالطبع dynamic عن الربط المتأخر، كما يلاحظ جون]).

نصائح أخرى

وطريقة لديك لم يتم تغيير value على أي حال - لماذا أنت تمرير فإنه بالرجوع؟ قد يكون من المنطقي، ولكن ليس واضحا حقا بالنسبة لي. لاحظ أن نموذج التعليمات البرمجية التي قمت بتوفيرها لن تجمع على أي حال، ولها الحجج ref أن <م> بالضبط نفس النوع كمعلمة.

و(أيضا، هل أنت على علم بأن C # 4.0 و. NET 4.0 سيكون قد بنيت في دعم لوقت متأخر ملزم؟ ما هي احتمالات أن إصدار متكاملة لغة سيكون أسهل استخداما من واحدة مكتبة فقط. هل أنت متأكد انه يستحق قضاء الوقت على المكتبة عند هذه النقطة في الوقت المناسب؟)

وتحرير: كود كنت قد قدمت حقا لن ترجمة. لم تحصل على الملاكمة لمعلمات ref، وتحديدا بسبب حجة والمعلمة أنواع يجب أن تكون بالضبط نفس الشيء. وإليك بعض التعليمات البرمجية لاثبات ذلك:

public class Test
{
    static void Main()
    {
        int i;
        Foo(ref i); // Won't compile - error CS1502/1503
    }

    static void Foo(ref object x)
    {
    }
}

إذا التعليمات البرمجية الحالية <م> هو تجميع، ثم انها ليست الشفرة التي قدمت في هذه المسألة. ربما لديك الزائد آخر لAddParameter التي تقبل ref int؟

وطيب، وذلك بفضل تصويبات جون السكيت ورمز كافة Gravell، لقد حان حتى مع هذه الواجهة:

        //This will be created with a factory
        IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());

        int param1 = 2;
        object paramObj = param1;

        invoker.AddParameter(ref paramObj).Invoke("MulFiveRef");

        param1 = (int)invoker.Parameters[0];

وليس بالضبط كما كنت أتخيل، ولكن هي طريقة أكثر بساطة وقابلية للقراءة أن بلدي الواجهة السابقة:

        IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>());
        int refValue = 10;
        object[] args = Args.Build(refValue);

        invoker.Call("MulFiveRef", Args.ByRefIndexs(0), args);

        refValue = (int)args[0];

وشكرا جزيلا للمساعدة شعبك:)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top