2012-02-11 3 views
3

생활 의 방법으로 파이썬여러 위치 매개를 인수 목록 전달 방법 있다는C#으로 여러 매개 변수 함수로 인수의 배열을 전달

def foo(b,a,r): 
    # bla bla bla 
    pass 

mylist = ['b','a','r'] 
foo(*mylist) 

짧다. 나는 기능을 터치 할 수없는 경우, 얼마나 상상

void foo(params string[] bar) 
{ 
    // bla bla bla 
} 

string[] mylist = {"b", "a", "r"}; 
foo(mylist) 

:

는하지만 C#으로 나는이 하나처럼 PARAMS에게 키워드를 사용하여 배열에 매개 변수를 배열을 통과 밖으로 발견 더 쉬운 방법이 있습니다. 그럴 수있는 방법이 있습니까? 여기

은 무슨 뜻입니다 :

void foo (string b, string a, string r) 
{ 
    // bla bla bla 
} 

string[] mylist = {"b", "a", "r"}; 
foo(mylist[0],mylist[1],mylist[2]); // This line makes my life difficult 

나는 온라인으로 검색하고 그 대안을 찾을 수 없습니다. C#에서 제공하는 숨겨진 기능을 놓치지 않았는지 확인하고 싶습니다. 우리에게 그런 지름길이 있다는 것을 누가 압니까?

+1

params 배열을 허용하도록 함수 매개 변수를 수정할 수 없다면 그렇게 할 수 없습니다. – Matthew

+3

'params'는 해결책이 될 것입니다. C#을 불공정 한 단점으로 간주합니다 .-) – BrokenGlass

+0

그러나 params 인수를 사용하면 메소드가 필요한 인수와 필요한 인수의 개수를 알 수 없습니다. 그래서 각 인수를 다른 변수 이름으로 구분하여 전달할 다음 매개 변수가 무엇인지 알 수 있습니다. – Yeo

답변

3

아니, 당신을 허용 C#에서 아무런 기능이 없다 이것을 직접하십시오. 하지만 해결하기 위해 당신이 사용할 수있는 몇 가지 방법이 있습니다 :

static Action<T[]> ToArrayMethod<T>(Action<T, T, T> original) 
{ 
    return array => original(array[0], array[1], array[2]); 
} 

그리고 다음처럼 사용

  1. 하나 개의 배열 매개 변수를 사용하는 방법에 여러 매개 변수와 방법을 변환하는 방법을 만들기 이 :

    string[] array = {"b", "a", "r"}; 
    
    var arrayFoo = ToArrayMethod(foo); 
    
    arrayFoo(array); 
    

    이 방법의 단점은이 방법 만 void 반환 형식과 정확히 세 개의 매개 변수와 방법에서 작동한다는 것입니다. 예를 들어 4 개 매개 변수가있는 메소드 또는 일부 값을 리턴하는 메소드에서 작동하게하려면 ToArrayMethod()의 또 다른 오버로드를 작성해야합니다.

  2. 반사를 사용하십시오.그 일을 할 때, 인수 배열을 사용하여 전달됩니다

    var foo = typeof(SomeType) 
        .GetMethod("foo", BindingFlags.Instance | BindingFlags.NonPublic); 
    
    object[] array = {"b", "a", "r"}; 
    
    foo.Invoke(somTypeInstance, array); 
    
+0

해결책 주셔서 감사합니다. -) – Yeo

1

이 정적 언어를 사용하는 단점이며, 함수 서명은 다음과 같이 정의 된 경우이 그들 중 하나입니다

void foo (string a, string b, string c); 
다음

당신은 3 별도의 문자열

foo(mylist[0],mylist[1],mylist[2]); 
전달하도록 강요

C#에서 유연한 입력을 얻는 유일한 방법은 매개 변수을 이미 사용하거나 기본값 (C# 4.0)을 사용하는 것입니다.

나는 B 통과하지 못한하거나 null로 설정 c는, 그리고 지금이 같은 함수를 호출 할 수 있다면 의미

:

foo(mylist[0]) 
+0

그러나 params string [] bar를 사용하면 필요한 인수를 알 수 없습니다. 그래서 각 인수를 변수로 구분합니다. – Yeo

+0

@YeoE 정확히, params에는 제한이 없으며 불행히도 배열 길이가 정확히 3이 아니면 서명 또는 오류를 통해 변경해야합니다. –

+0

감사합니다. – Yeo

0

지름길이 없습니다. 당신이 미치고 싶다면 함수를 다소 수정할 수 있다면, params 키워드를 가진 하나의 서명을 갖도록 오버로드하고 원래의 오버로드가 새로운 인수에 인수를 전달하도록 할 수 있습니다.

1

리플렉션을 사용할 수 있습니다. 그러나 일반적으로 컴파일 타임 유형 안전 검사를 희생 시키므로 권장하지 않습니다.

그래서
string[] mylist = { "b", "a", "r" }; 
((Action<string,string,string>)foo).DynamicInvoke(mylist); 
+0

메모를 주셔서 감사합니다 ... 나는 형식 안전 검사를 의미합니다 :) – Yeo

0

당신이 이것에 대한 해킹의 일종 내 의견에 가장 깨끗한 방법이 필요합니다, 여기에 답변을 많이 요약이 라인을 따라 뭔가하기 : 여기

은 샘플 방법입니다 :

는 enumerables 대한 확장 기능을 작성

이어서
public static class Extensions 
{ 
    public static void SendToMethod<T>(this IEnumerable<T> self, Delegate func ) 
    { 
     Contract.Requires(func.Method.GetParameters().Length == self.Count()); 
     func.DynamicInvoke(self.Cast<object>().ToArray()); 
    } 
} 

는 인수가 열거의 길이와 동일한 개수를 갖는 임의의 함수 배열을 보낼 수

public void foo(string a, int b, bool c, string d) {} 
public void foo2(string a, string b, string c) {} 

... 
var test1 = new object[] {"ASDF", 10, false, "QWER"}; 
var test2 = new[] {"A", "B", "C"}; 

test2.SendToMethod((Action<string, string, string>)foo); 
test1.SendToMethod((Action<string, int, bool, string>)foo2); 
+0

개인적으로, 나는 그것이 "뒤로"있기 때문에 개인적으로, 나는 이것을 좋아하지 않습니다. 'method.InvokeWithArray (array)'와 같은 것은 나에게 더 이해가된다. 또한, 각 버전의'Action'에 오버로드를줌으로써 캐스트를 피할 수 있습니다. – svick

관련 문제