Interfejs przekazany do metody - potrzebne propercje klasy implementującej

0

Mam interfejs przekazany do metody.
Interfejs ten implementuje wiele klas, lecz w jednej z tych klas mam dodatkowe propercje.
Chciałbym użyć tych dodatkowych propercji w metodzie gdzie przekazuje interfejs.
Jak to najlepiej zrobić ?
Nie chce rozszerzać interfejsu o te propercje bo nie sa mi potrzebne w innych klasach.

1

Podaj jakis przyklad.

Dlaczego dlaczego w uniwersalne j metodzie oczekujesz konkretnej implementacji? Co sie stanie jesli jej nie otzrymasz? Jak sprawdzasz czy to dobry element? Castujesz? Jesli tak to jaki jest problem? Czy mozesz przenieść te metode do interfejsu? Czy mozesz przeniesc te metode na poziom internal? I pracowac na implementacjach?

1

Jeśli nie chcesz rozszerzać interfejsu (co jest dobrą decyzją w myśl interface segregation principle) to jednym z rozwiązań może być przyjęcie że przekazywany, abstrakcyjny obiekt może wymagać dodatkowego przetwarzania. Wtedy możesz np. użyć jakiejś fabryki która- sprawdzając konkretny typ obiektu- zwróci np. jakiś obiekt przetwarzający (procesor), z kolei ten procesor będzie posiadał logikę operującą na obiekcie konkretnego typu. Z tym że to nie jest rozwiązanie idealne i zapewne da się rozwiązać Twój problem lepiej. Ciężko jednak coś więcej doradzić nie znając konkretów Twojego kodu.

Przykład:

public interface ISomething
{
  string ValueOne { get; }
}

public interface ISomethingElse : ISomething
{
  string ValueTwo { get; }
}

public interface IProcessor
{
    void Process(ISomething something);
}

public class ProcessorFactory
{
  public IProcessor Create(ISomething something)
  {
     return something switch
     {
        ISomethngElse _ => new SomethingElseProcessor(),
       _ => new SomeGenericProcessor()
     };
  }
}

public class SomethingElseProcessor : IProcessor
{
  public void Process(ISomething something)
  {
    // Rzutujesz na konkretny typ. Oczywiście zakłada to żę metoda zawsze otrzyma odpowiedni obiekt, w przeciwnym razie dostaniesz tutaj wyjątek.
    var concrete = (ISomethingElse)something;
    var valueTwo = concrete.ValueTwo;
    // Wykonaj logikę konkretną dla tego typu
  }
}

public class Client
{
  public void Process(ISomething something)
  {
    var valueOne = something.ValueOne;
    // Zrób coś z valueOne

   // Stwórz instancję procesora
   var processor = _processorFactory.Create(something);
   processor.Process(something);
  }
}
2

Napisz po prostu przeciążoną wersję metody przyjmującą klasę.

1
seth01 napisał(a):

Mam interfejs przekazany do metody.
Interfejs ten implementuje wiele klas, lecz w jednej z tych klas mam dodatkowe propercje.

Powinno być "Interfejs jest implementowany przez wiele klas".
Więc przede wszystkim jest jakiś problem w samej architekturze, bo zazwyczaj takie rzeczy o tym świadczą.

Najprościej, ale zaznaczam, że nie najlepiej jest zrobić po prostu:

public void Metoda(IInterfejs obj)
{
  SuperKlasa c = obj as SuperKlasa;
  if(c != null)
  {
     //i lecisz z właściwościami
  }
}

To NIE jest dobre rozwiązanie, ale najszybsze.

0
Juhas napisał(a):

Najprościej, ale zaznaczam, że nie najlepiej jest zrobić po prostu:

public void Metoda(IInterfejs obj)
{
  SuperKlasa c = obj as SuperKlasa;
  if(c != null)
  {
     //i lecisz z właściwościami
  }
}

To NIE jest dobre rozwiązanie, ale najszybsze.

panią Liskov gwałcono tak często że w C# 7 jest na to nawet specjalna składnia:

public void Metoda(IInterfejs obj)
{
  if(obj is SuperKlasa c)
  {
     //i lecisz z właściwościami
  }
}

ale ogólnie pomyśl nad interfejsami. Jeżeli w metodzie wymagasz tych właćiwości to może wcale nie oczekujesz interfejsu tylko konkretnej klasy? A może warto stworzyć nowy interfejs bazujący na tamtym? Musiałbyś się podzielić swoim kodem jeśli chcesz poprawne rozwiązanie.

0
obscurity napisał(a):

panią Liskov gwałcono tak często że w C# 7 jest na to nawet specjalna składnia:

To nie jest składnia do gwałcenia dobrych zasad tylko type pattern.

1 użytkowników online, w tym zalogowanych: 0, gości: 1