2009-09-25 17 views
8

Właśnie napotkałem coś z C# dzisiaj, o którym wcześniej nie myślałem. Mam dwie metody w mojej klasie, jedną przeciążającą drugą. Są one zadeklarowane tak:C# parametr params z dwoma parametrami tego samego typu

1) public void RequirePermissions(params string[] permissions)... 
2) public void RequirePermissions(string message, params string[] permissions)... 

W moim kodu, próbowałem zadzwonić pierwszy z nich w taki sposób:

RequirePermissions("Permission1", "Permission2"); 

... spodziewałem się nazywać pierwszy przeciążenie. Cóż, nazwała drugie przeciążenie. Jedynym sposobem mogę je nazwać pierwszą metodę w tym przypadku jest ręcznie przekazać string [] obiekt tak:

RequirePermissions(new string[] { "Permission1", "Permission2" }); 

Teraz takie zachowanie nie mylić mnie, bo rozumiem, że kompilator powiedzieć, którą metodę faktycznie chciałem wywołać na podstawie podanych przeze mnie parametrów. Ale czy nie byłbym ostrożny, to mogło zostać niezauważone w moim kodzie. Wygląda na to, że Microsoft powinien zmusić kompilator do zgłoszenia błędu, gdy napotkał sytuację podobną do powyższej. Czy ktoś ma jakieś przemyślenia na ten temat? Czy istnieje inny sposób na wywołanie pierwszego przeciążenia niż "rozwiązanie", które napisałem?

+0

Zajrzyj tutaj - http://ayende.com/Blog/archive/2007/12/31/Tricky-Code.aspx i tutaj- http: //www.yoda.arachsys .com/csharp/teasers.html (no 6) – RichardOD

+1

Jestem nieco zdezorientowany twoją sugestią. Czy uważasz, że ostrzeżenie powinno dotyczyć niejednoznacznego * połączenia * lub zestawu * deklaracji *, które mogłyby prowadzić do niejednoznacznego połączenia? –

Odpowiedz

2

Tak, zgadzam się, że powinno to być ostrzeżeniem, gdy użycie tablic argumentów o zmiennej długości powoduje niejednoznaczne przeciążenie - to bardzo poważny przypadek, a ludzie prawie na pewno nie chcą tworzyć takich sytuacji.

Ja też nie znam żadnej innej, poza tą, którą opublikowałeś, aby uniknąć rozstrzygnięcia połączenia, które ma miejsce - inaczej niż unikanie tego w pierwszej kolejności, co gorąco polecam!

0

Nie można używać parametrów i jawnie z podpisami.

public void RequirePermissions(string[] permissions)... 
public void RequirePermissions(string message, string[] permissions).. 
7

Zgadzając się z Adamem, to bym go zmienić na coś takiego:

public void RequirePermissions(params string[] permissions) 

public void RequirePermissionsWithMessage(string message, params string[] permissions) 
+0

Cholera, nie zauważyłem twojej odpowiedzi, dopóki nie opublikuję mojej. Paski przewijania w próbkach kodu sprawiają, że moje oczy są oszklone, jak sądzę. – MusiGenesis

+0

@scottm: podobno nie. * Ja * głosowałem * twoja * odpowiedź w górę. :) – MusiGenesis

7

Osobiście zrobiłbym to w ten sposób:

1) public void RequirePermissions(params string[] permissions)... 
2) public void RequireMessageAndPermissions(string message, 
     params string[] permissions)... 

ludzie wpadają zbyt zakochana przeładowanie czasem, a kiedy łączysz to z miłością do słowa kluczowego params, po prostu zwiększasz poziom zamieszania dla kogoś, kto ostatecznie musi przejąć twój kod.

+0

+1 Dobry pomysł, jeszcze bardziej wyraźny –

3

Wygląda na to, że nie ma innej drogi.

można znaleźć wyjaśnienie tego problemu w C# specyfikacji http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm i tutaj http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (pkt 2)

tablica parametr jest właśnie odpowiednikiem wartości parametru (§17.5.1.1) tego samego typu.

i

Spieniony postaci sposobu jest dostępna tylko wtedy, gdy normalnie postać sposobu nie zastosowanie i tylko wtedy, gdy sposób tego samego podpisu jak rozszerzonej formie nie jest już zadeklarowane w tym samym typie:

Powiązane problemy