سؤال

تخيل طريقة مع التوقيع التالي:

public void ExampleMethod(string id, object data, 
                          ref object A, ref object B, ref object C)
{
  //...
}

القيمة في data يحتاج إلى تعيين إما A, B, C أو لا شيء ، اعتمادا على قيمة id.باختصار ، إذا id == "A" ثم A = data;

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

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

public void ExampleMethod(string id, object data, 
                          ref object A, ???????, ref object Z)
{
  MethodBase method = MethodBase.GetCurrentMethod();
  foreach (ParameterInfo parameter in method.GetParameters())
  { 
    if (id == parameter.Name)
    {
      // Problem: assign data to parameter.
      return;
    }
  }
}
هل كانت مفيدة؟

المحلول

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

public void ExampleMethod(string id, object data,
        IDictionary<string,object> args) {
    args[id] = data;
}

لست متأكدا مما إذا كان ذلك يساعد...ولكن ما تحاول القيام به ليس حقا التفكير ودية.الخيار الآخر هو إنشاء هذه الطريقة ديناميكيا ، إما كجزء من عملية البناء الخاصة بك ، أو عن طريق إيل.إما أن يكون على ما يرام.لذلك يمكن أن تولد أساسا (إما ج # أو (في وقت التشغيل) إيل):

public void ExampleMethod(string id, object data, 
                          ref object A, ref object B, ref object C)
{
    switch(id) {
        case "A": A = data; break;
        case "B": B = data; break;
        case "C": C = data; break;
        default: /* do something */
    }
}

نهج إضافي:الكائن المكتوب:قل لديك:

public void ExampleMethod(string id, object data, SomeType obj) {...}

أين obj هو كائن له خصائص مثل "أ" ، " ب " ، "ج";ثم ما تحاول توليد هو:

switch(id) {
    case "A": obj.A = data; break;
    case "B": obj.B = data; break;
    case "C": obj.C = data; break;
    default: /* do something */
}

والتي يمكن بالطبع القيام به مع التفكير:

var prop = obj.GetType().GetProperty(id);
prop.SetValue(obj, data, null);

أو إذا كان الأداء حرجا ، شيء من هذا القبيل سريع-عضو:

var wrapped = ObjectAccessor.Create(obj); 
wrapped[id] = data;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top