programing tip

단일 객체 []를 params 객체에 전달하는 방법 []

itbloger 2020. 7. 17. 20:57
반응형

단일 객체 []를 params 객체에 전달하는 방법 []


params object []를 사용하는 메소드가 있습니다.

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) 또는 Adam 에서 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 );

편집 : Raymond Chen은이 동작과 새 게시물 의 C # 사양과 관련이있는 방법을 설명합니다 .


이것은 LINQ와 관련된 한 줄 솔루션입니다.

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

다음과 같이 다른 object [] 배열로 캡슐화해야합니다.

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

이 문제를 해결하는 또 다른 방법 (좋은 습관은 아니지만 아름다움을 보입니다) :

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

용법:

f(new object[] { 1, 2, 3 }.AsSingleParam());

한 가지 옵션은 다른 배열로 감싸는 것입니다.

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

못생긴 종류이지만 각 항목이 배열이므로 문제를 해결하기 위해 캐스트 할 수는 없습니다. 예를 들어 Foo (params object items)와 같은 경우에는 다음을 수행 할 수 있습니다.

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

Alternatively, you could try defining another overloaded instance of Foo which takes just a single array:

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 }

참고URL : https://stackoverflow.com/questions/36350/how-to-pass-a-single-object-to-a-params-object

반응형