تحديد وسيطات الأسلوب المسماة والاختيارية

مكتمل

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

عند استخدام الوسيطات المسماة والاختيارية، يتم تقييم الوسيطات بالترتيب الذي تظهر به في قائمة الوسيطات، وليس في قائمة المعلمات.

تمكنك المعلمات المسماة والاختيارية من توفير وسيطات للمعلمات المحددة. تسهل هذه الإمكانية إلى حد كبير المكالمات إلى واجهات COM مثل واجهات برمجة تطبيقات أتمتة Microsoft Office.

الوسيطات المسماة

تحررك الوسيطات المسماة من مطابقة ترتيب الوسيطات مع ترتيب المعلمات في قوائم المعلمات للأساليب المسماة. يمكن تحديد الوسيطة لكل معلمة بواسطة اسم المعلمة.

ملاحظه

تعمل الوسيطات المسماة على تحسين قابلية قراءة التعليمات البرمجية الخاصة بك عن طريق تحديد ما تمثله كل وسيطة.

خذ بعين الاعتبار أسلوب يستخدم توقيع الأسلوب التالي:


static void PrintOrderDetails(string sellerName, int orderNum, string productName)
{
    // Code to print the order details
}

يمكن استدعاء هذا الأسلوب بنجاح دون استخدام وسيطات مسماة طالما أن الوسيطات بالترتيب الصحيح (المعرفة بواسطة توقيع الأسلوب):


PrintOrderDetails("Gift Shop", 31, "Red Mug");

إذا كنت لا تتذكر ترتيب المعلمات ولكنك تعرف أسماءها، يمكنك إرسال الوسيطات بأي ترتيب.


PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

عند استخدامها مع الوسيطات الموضعية، تكون الوسيطات المسماة صالحة طالما يتم استخدامها في الموضع الصحيح.

يعمل المثال التالي بشكل صحيح لأن: المعلمة productName مسماة بشكل صريح، ولا تتبعها أي وسيطات موضعية، وهي في الموضع الصحيح.


PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");

الوسيطات الموضعية التي تتبع أي وسيطات مسماة خارج الترتيب غير صحيحة.


// This generates CS1738: Named argument specifications must appear after all fixed arguments have been specified.
PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");

الوسيطات الاختيارية

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

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

  • تعبير ثابت، مثل سلسلة حرفية أو رقم.
  • تعبير النموذج new ValType()، حيث ValType هو نوع قيمة، مثل enum أو struct.
  • تعبير للنموذج default(ValType)، حيث ValType هو نوع قيمة.

يتم تعريف المعلمات الاختيارية في نهاية قائمة المعلمات، بعد أي معلمات مطلوبة. يجب أن يوفر المتصل وسيطات لكافة المعلمات المطلوبة وأي معلمات اختيارية تسبق تلك التي يحددها. الثغرات المفصولة بفواصل في قائمة الوسيطات غير مدعومة. على سبيل المثال، في التعليمات البرمجية التالية، يتم تعريف أسلوب المثيل ExampleMethod بمعلمة واحدة مطلوبة ومعلمتين اختياريتين.


public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10)

يؤدي الاستدعاء التالي إلى ExampleMethod إلى حدوث خطأ في المحول البرمجي، لأنه يتم توفير وسيطة للمعلمة الثالثة ولكن ليس للمعلمة الثانية.


// anExample.ExampleMethod(3, ,4);

ومع ذلك، إذا كنت تعرف اسم المعلمة الثالثة، يمكنك استخدام وسيطة مسماة لإنجاز المهمة.


anExample.ExampleMethod(3, optionalint: 4);

يستخدم IntelliSense الأقواس للإشارة إلى المعلمات الاختيارية، كما هو موضح في الرسم التوضيحي التالي:

لقطة شاشة توضح كيفية استخدام IntelliSence للأقواس للإشارة إلى المعلمات الاختيارية.

ملاحظه

يمكنك أيضا تعريف المعلمات الاختيارية باستخدام فئة .NET OptionalAttribute. لا تتطلب المعلمات OptionalAttribute قيمة افتراضية. ومع ذلك، إذا كانت هناك قيمة افتراضية مطلوبة، ففكر في استخدام فئة DefaultParameterValueAttribute.

في المثال التالي، تحتوي الدالة الإنشائية ExampleClass على معلمة واحدة، وهي اختيارية. يحتوي أسلوب ExampleMethod المثيل على معلمة واحدة مطلوبة، required، ومعلمتين اختياريتين، optionalstroptionalint. توضح التعليمات البرمجية في Main الطرق المختلفة التي يمكن من خلالها استدعاء الدالة الإنشائية والأسلوب.


namespace OptionalNamespace
{
    class OptionalExample
    {
        static void Main(string[] args)
        {
            // Instance anExample does not send an argument for the constructor's
            // optional parameter.
            ExampleClass anExample = new ExampleClass();
            anExample.ExampleMethod(1, "One", 1);
            anExample.ExampleMethod(2, "Two");
            anExample.ExampleMethod(3);

            // Instance anotherExample sends an argument for the constructor's
            // optional parameter.
            ExampleClass anotherExample = new ExampleClass("Provided name");
            anotherExample.ExampleMethod(1, "One", 1);
            anotherExample.ExampleMethod(2, "Two");
            anotherExample.ExampleMethod(3);

            // The following statements produce compiler errors.

            // An argument must be supplied for the first parameter, and it
            // must be an integer.
            //anExample.ExampleMethod("One", 1);
            //anExample.ExampleMethod();

            // You can't leave a gap in the provided arguments.
            //anExample.ExampleMethod(3, ,4);
            //anExample.ExampleMethod(3, 4);

            // You can use a named parameter to make the previous
            // statement work.
            anExample.ExampleMethod(3, optionalint: 4);
        }
    }

    class ExampleClass
    {
        private string _name;

        // Because the parameter for the constructor, name, has a default
        // value assigned to it, it's optional.
        public ExampleClass(string name = "Default name")
        {
            _name = name;
        }

        // The first parameter, required, has no default value assigned
        // to it. Therefore, it isn't optional. Both optionalstr and
        // optionalint have default values assigned to them. They're optional.
        public void ExampleMethod(int required, string optionalstr = "default string",
            int optionalint = 10)
        {
            Console.WriteLine(
                $"{_name}: {required}, {optionalstr}, and {optionalint}.");
        }
    }

    // The output from this example is the following:
    // Default name: 1, One, and 1.
    // Default name: 2, Two, and 10.
    // Default name: 3, default string, and 10.
    // Provided name: 1, One, and 1.
    // Provided name: 2, Two, and 10.
    // Provided name: 3, default string, and 10.
    // Default name: 3, default string, and 4.
}

دقة التحميل الزائد للوسيطات المسماة والاختيارية

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

يؤثر استخدام الوسيطات المسماة والاختيارية على دقة التحميل الزائد بالطرق التالية:

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