كيفية تمرير كائن واحد[] إلى params كائن[]

StackOverflow https://stackoverflow.com/questions/36350

  •  09-06-2019
  •  | 
  •  

سؤال

لدي الأسلوب الذي يأخذ params كائن[] مثل:

void Foo(params object[] items)
{
    Console.WriteLine(items[0]);
}

عندما تمر اثنين من وجوه صفائف إلى هذا الأسلوب يعمل بشكل جيد:

Foo(new object[]{ (object)"1", (object)"2" }, new object[]{ (object)"3", (object)"4" } );
// Output: System.Object[]

ولكن عندما تمر كائن واحد[], لأنها لا تأخذ بلدي كائن[] أول المعلمة, بدلا من ذلك فإنه يأخذ جميع العناصر مثل أردت أن تمر عليهم واحدا تلو الآخر:

Foo(new object[]{ (object)"1", (object)"2" });
// Output: 1, expected: System.Object[]

كيف يمكنني تمرير كائن واحد[] الأولى الحجة إلى params المصفوفة ؟

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

المحلول

بسيطة التلبيس سوف تضمن المترجم يعرف ماذا تعني في هذه الحالة.

Foo((object)new object[]{ (object)"1", (object)"2" }));

كما صفيف هو نوع فرعي من وجوه ، كل هذا يعمل بها.غريبا الحل على الرغم من أنني سوف نوافق على ذلك.

نصائح أخرى

على params المعلمة التعديل يعطي المتصلين اختصار الجملة من أجل تمرير متعددة الوسائط إلى طريقة.هناك طريقتان استدعاء الأسلوب مع params المعلمة:

1) الاتصال مع مجموعة من نوع المعلمة في هذه الحالة params الكلمة ليس له تأثير و يتم تمرير مجموعة مباشرة إلى الأسلوب:

object[] array = new[] { "1", "2" };

// Foo receives the 'array' argument directly.
Foo( array );

2) أو الاتصال مع قائمة طويلة من الحجج ، وفي هذه الحالة فإن المترجم تلقائيا التفاف قائمة الحجج مؤقت مجموعة وتمرير هذا الأسلوب:

// Foo receives a temporary array containing the list of arguments.
Foo( "1", "2" );

// This is equivalent to:
object[] temp = new[] { "1", "2" );
Foo( temp );


من أجل تمرير صفيف كائن إلى الأسلوب مع "params object[]"المعلمة ، يمكنك إما:

1) إنشاء المجمع مجموعة يدويا و يمر مباشرة إلى طريقة ، كما ذكر من قبل lassevk:

Foo( new object[] { array } );  // Equivalent to calling convention 1.

2) أو يلقي الحجة object, كما ذكر من قبل آدم, في هذه الحالة فإن المترجم إنشاء المجمع مجموعة بالنسبة لك:

Foo( (object)array );  // Equivalent to calling convention 2.


ومع ذلك ، إذا كان الهدف من الطريقة هو عملية متعددة كائن المصفوفات ، قد يكون من الأسهل أن يعلن ذلك مع صريح "params object[][]"المعلمة.هذا من شأنه أن تسمح لك تمرير صفائف متعددة كما الحجج:

void Foo( params object[][] arrays ) {
  foreach( object[] array in arrays ) {
    // process array
  }
}

...
Foo( new[] { "1", "2" }, new[] { "3", "4" } );

// Equivalent to:
object[][] arrays = new[] {
  new[] { "1", "2" },
  new[] { "3", "4" }
};
Foo( arrays );

تحرير: ريمون تشن يصف هذا السلوك ومدى ارتباطه C# مواصفات في وظيفة جديدة.

هذا هو سطر واحد حل تنطوي LINQ.

var elements = new String[] { "1", "2", "3" };
Foo(elements.Cast<object>().ToArray())

تحتاج لتغليف إلى كائن آخر[] مجموعة, مثل هذا:

Foo(new Object[] { new object[]{ (object)"1", (object)"2" }});

خيار واحد هو أن تتمكن من ألفه إلى مجموعة أخرى:

Foo(new object[]{ new object[]{ (object)"1", (object)"2" } });

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

Foo((object) new object[]{ (object)"1", (object)"2" });

بدلا من ذلك, يمكنك أن تحاول تحديد آخر زائد مثيل فو الذي يأخذ واحدة فقط مجموعة:

void Foo(object[] item)
{
    // Somehow don't duplicate Foo(object[]) and
    // Foo(params object[]) without making an infinite
    // recursive call... maybe something like
    // FooImpl(params object[] items) and then this
    // could invoke it via:
    // FooImpl(new object[] { item });
}
new[] { (object) 0, (object) null, (object) false }

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

static class Helper
{
    public static object AsSingleParam(this object[] arg)
    {
       return (object)arg;
    }
}

الاستخدام:

f(new object[] { 1, 2, 3 }.AsSingleParam());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top