Załóżmy, że mam dwie klasy, które wyglądają tak (pierwszy blok kodu i ogólny problem są związane z C #):
class A
{
public int IntProperty { get; set; }
}
class B
{
public int IntProperty { get; set; }
}
Klasy te nie mogą być w żaden sposób zmieniane (są częścią zespołu zewnętrznego). Dlatego nie mogę zmusić ich do wdrożenia tego samego interfejsu ani dziedziczenia tej samej klasy, która zawierałaby IntProperty.
Chcę zastosować logikę do IntProperty
właściwości obu klas, aw C ++ mógłbym użyć klasy szablonów, aby to zrobić dość łatwo:
template <class T>
class LogicToBeApplied
{
public:
void T CreateElement();
};
template <class T>
T LogicToBeApplied<T>::CreateElement()
{
T retVal;
retVal.IntProperty = 50;
return retVal;
}
A potem mógłbym zrobić coś takiego:
LogicToBeApplied<ClassA> classALogic;
LogicToBeApplied<ClassB> classBLogic;
ClassA classAElement = classALogic.CreateElement();
ClassB classBElement = classBLogic.CreateElement();
W ten sposób mogłem stworzyć jedną ogólną klasę fabryczną, która działałaby zarówno dla ClassA, jak i ClassB.
Jednak w języku C # muszę napisać dwie klasy z dwoma różnymi where
klauzulami, mimo że kod dla logiki jest dokładnie taki sam:
public class LogicAToBeApplied<T> where T : ClassA, new()
{
public T CreateElement()
{
T retVal = new T();
retVal.IntProperty = 50;
return retVal;
}
}
public class LogicBToBeApplied<T> where T : ClassB, new()
{
public T CreateElement()
{
T retVal = new T();
retVal.IntProperty = 50;
return retVal;
}
}
Wiem, że jeśli chcę mieć różne klasy w where
klauzuli, muszą one być powiązane, tj. Aby odziedziczyć tę samą klasę, jeśli chcę zastosować do nich ten sam kod w sensie, który opisałem powyżej. Po prostu dwie denerwujące metody są bardzo denerwujące. Nie chcę też używać refleksji z powodu problemów z wydajnością.
Czy ktoś może zasugerować jakieś podejście, w którym można to napisać w bardziej elegancki sposób?