2012-06-26 9 views
6

Pracuję nad rozwojem zewnętrznego interfejsu API. I dodaje metodę do mojego publicznego interfejsu:Zmiana nazwy tylko z powodu Null?

public void AddMode(TypeA mode); 
public void AddMode(TypeB mode); // the new method, TypeB and TypeA are not related at all 

wyglądało to dobrze, dopóki nie złamał jeden test, który został przechodzącą null. To spowodowało, że kompilator pomylił się z niejednoznacznym wywołaniem. Naprawiłem test, rzucając null.

Jednak moje pytanie brzmi:

  • powinienem zmienić nazwę właśnie z tego powodu?
  • Czy powinien pozwolić klientowi obsadzić obsadę tak jak ja? (jeśli z jakiegokolwiek powodu przekazują wartość zerową)

Co jest najlepsze w tym przypadku podczas projektowania interfejsów API?

Edit:

połączenie było jak ten AddMode (null), nie podoba:

TypeA vl = null; 
AddMode(v1); // this doesn't cause a problem 
+1

Podobny problem tutaj [mijający null] (http://stackoverflow.com/questions/719546/c-passing-null-to-overloaded-method-which- metode- jest-) był polecany (doskonały odpowiedź) – V4Vendetta

+0

@MBen - Proponuję zmienić nazwę metod. – adatapost

+0

@ V4Vendetta Widziałem to przed opublikowaniem :-). Jednak zastanawiam się nad użytecznością API, jeśli powinienem pozwolić, aby klient wpadł w to. Nie rozumiem, dlaczego nazwaliby tą metodą wartością zerową, ale kto wie :-) – MBen

Odpowiedz

6

Interfejs API powinien być zaprojektowany tak, aby był łatwy w użyciu i niepoprawnie używany. Twój API jest łatwy w użyciu poprawnie:

AddMode(new TypeA()); 

skompilować.

Jest trudniejszy w obsłudze niepoprawnie:

AddMode(null); 

nie kompiluje. Użytkownik ist zmuszony zrobić coś jak

AddMode((TypeA)null); 

który powinien mu myśleć, czy to jest spodziewane zużycie. Więc myślę, że twoje API jest w porządku, tak jak jest.

+0

Podoba mi się to. Nie widziałem tego z tej perspektywy. – MBen

1

myślę, że zależy od tego jak wyjątkowa null jako wartość dla danego argumentu jest .

Porównaj na przykład this ArgumentNullException constructor: Najczęściej jest wywoływana, gdy trzeba ustawić wewnętrzny wyjątek. W przeciwnym razie zostanie przekazany this constructor, który oprócz nazwy nielegalnego argumentu. Przy innych okazjach należy wywoływać ten pierwszy, ponieważ należy podać niestandardowy komunikat, ale nie podano wyjątku wewnętrznego (zazwyczaj robię to, gdy wyrzucam wyjątek dla argumentu tablica/kolekcja, który zawiera null, ale nie jest null). Tak więc w tym przypadku potrzebuję wyraźnej obsady i powiedziałbym, że jest do przyjęcia.

Jeśli metody naprawdę zrobić to samo, ale null nadal jest zwykle wartość, warto dodać przeciążenie bez parametrów dla wariantu null (czyli jawne obsada jest nadal możliwe, ale użytkownicy mogą również wywołać przeciążenie bez parametrów zamiast).

Jeśli metody zrobić coś nieco innego, a jeszcze coś innego dla null, można myśleć o zabronienie null zupełnie dla metod już pokazane i dodanie przeciążenie bez parametrów dla przypadku null.

Aktualizacja: Jeśli mimo to null jest niedopuszczalne (i spowoduje wyjątek), należy pozostawić tę metodę bez zmian. Poza testowaniem, nigdy nie powinno być jakiejkolwiek sytuacji, w której literał null zostałby przekazany do metody, ponieważ będzie to niezmiennie powodować wyjątek. Dlatego nie zmieniaj w tym przypadku nazw przeciążeń.

+0

Ale wartość null jest niedopuszczalna, generuję ArgumentNullException w obu metodach. Jednak błąd, który widzę, występuje w czasie kompilacji podczas przekazywania wartości NULL takiej jak ta Addmode (null). – MBen

+0

Sprawdź moją edycję, aby uzyskać lepsze wyjaśnienie. – MBen

+0

@MBen: Zaktualizowałem moją odpowiedź, aby wziąć to pod uwagę. –

0

Czy mimo to jest puste wejście do tej metody?

Osobiście bym go zostawić jak jest tak długo, jak oba przeciążenia AddMode powiązane, ponieważ można się spodziewać AddMode (X) i (Y) AddMode się robić coś ze sobą powiązane.

Jeśli nie są one związane w jakikolwiek sposób, to może zmiana nazwy metody jest w porządku

0

Cóż, to zależy zarówno null wartość dopuszczalne wartość w API.

Jeśli nie tylko nie akceptuj tego, nie wspierając go. Tak więc, nawet jeśli konsument będzie próbował spróbować, aby użyć go z null, kompilator złamie problem niejednoznaczności.

+0

Cóż, wartość null jest nie do przyjęcia, ale błąd występuje w czasie kompilacji. – MBen

+0

@MBen: nie chcesz, żeby to był czas kompilacji? – Tigran

+0

hi @Tigran sprawdź moją aktualizację. – MBen

0

Jeśli twój interfejs API przyjmuje wartość zerową jako możliwą wartość parametru, musisz ją określić w dokumentacji i wspomnieć, że trzeba ją przesłać, i napisać kilka przykładów kodu, aby pokazać, jak.

Jeśli jednak nie chcesz, aby użytkownik używał wartości pustych, możesz zmienić TypeA i TypeB na struct zamiast na , jeśli pozwalają na to projekty klas.