Rozważmy następujące klasyJak utworzyć interfejs, który zachowuje niektóre metody wewnętrzne do testowania w języku C#?
public class Entity {
public void Foo() { ... }
internal void Bar() { ... }
}
Jak widać ma public
sposób i metodę internal
. Teraz chciałbym stworzyć interfejs, który pozwoli mi naśmiewać się z tej klasy w testach (zarówno w tym zespole, jak iw innych). Przepisuję mój kod w następujący sposób:
public interface IEntity {
void Foo();
}
internal class Entity : IEntity {
public void Foo() { ... }
public void Bar() { ... }
}
Jednak tworzy to kolejny problem. Przy użyciu klasy w inny sposób, w tym samym zespole nie mogę nazwać Bar
już:
public class OtherClass {
public void SomeMethod(IEntity entity) {
entity.Bar(); // error!
}
}
Przepisanie kodu tak:
public class OtherClass {
public void SomeMethod(IEntity entity) {
(entity as Entity).Bar(); // error in test!
}
}
spowoduje błąd w badanej jednostki, która wyzwala SomeMethod
. Jak przerobić mój kod, aby nadal korzystać z metod internal
w tym samym asemblowaniu, a jedynie wystawiać publicznych członków na inne zespoły?
Aktualizacja: Klasa OtherClass
jest klasą narzędzie, które musi działać na wewnętrzne klasy Entity
, które nie są narażone na użytkowników bezpośrednio. Jednak sama ta klasa jest narażona na działanie użytkowników, więc pośrednio mają dostęp do wewnętrznych elementów urządzenia Entity
. Jest to pożądane, ponieważ SomeMethod
przeprowadzi niezbędne kontrole w celu upewnienia się, że użytkownicy nie zepsują stanu wewnętrznego obiektu Entity
.
Dlaczego po prostu nie uczynisz metod wirtualnych zamiast tworzyć interfejs? – adrianm
@adrianm: Ponieważ chcę również przejrzysty interfejs dla użytkowników, nie pomieszany z członkami prywatnymi/wewnętrznymi i implementacją. A także dlatego, że chciałbym móc zapewnić inną implementację w przyszłości bez odbudowy wszystkich zależnych projektów. Biorąc jednak pod uwagę wszystkie trudności, jakie stwarzają interfejsy w kontaktach z członkami wewnętrznymi, mogę wybrać tę opcję pomimo powyższych zalet. –