簡體   English   中英

在C#中將Argument數組傳遞給多參數函數

[英]Passing array of Argument into multiple parameter function in C#

生命短暫

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

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

這就是如何參數列表傳遞給 Python中的方法多個位置參數

但在C#中,我發現使用params關鍵字將數組傳遞給數組 參數 ,如下所示:

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

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

想象一下如果我無法觸摸該功能,是否有更簡單的方法有沒有辦法做到這一點?

這就是我的意思:

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#提供的隱藏功能。 誰知道我們有這樣的捷徑?

不,C#中沒有允許您直接執行此操作的功能。 但是有一些方法可以用來解決這個問題:

  1. 創建一個方法,將具有多個參數的方法轉換為具有一個數組參數的方法:

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

    然后像這樣使用它:

     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); 

使用靜態語言存在缺點,如果您的函數簽名定義為:

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

然后你被迫傳入3個單獨的字符串

foo(mylist[0],mylist[1],mylist[2]);

在C#中使用靈活輸入的唯一方法是使用現在已經使用的params ,或者使用默認值(C#4.0):

void foo (string a, string b = null, string c = null)

意思是如果我沒有傳遞b或c只是將它們設置為null,現在你可以像這樣調用你的函數:

foo(mylist[0]) 

你可以用反射; 但是,通常不推薦這樣做,因為它會讓您犧牲編譯時類型安全檢查。

這是一個示例方法:

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

沒有捷徑。 如果你想變得瘋狂並且你能夠稍微修改一下這個函數,你可以重載它以使用params關鍵字簽名,並讓原始重載將其參數傳遞給新的。

所以總結一下這里的很多回復,你需要一個這樣的黑客,我認為最干凈的方式就是這樣:

為枚舉創建擴展函數:

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); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM