funkcja ogólna z ograniczeniem „ma właściwość X”?
Mam zamkniętą aplikację źródłową innej firmy, która eksportuje interfejs COM, którego używam w mojej aplikacji C # .NET przez Interop. Ten interfejs COM eksportuje wiele obiektów, które wszystkie są wyświetlane jako System.Object, dopóki nie rzucę ich na odpowiedni typ interfejsu. Chcę przypisać właściwość wszystkich tych obiektów. A zatem:
foreach (object x in BigComInterface.Chickens)
{
(x as Chicken).attribute = value;
}
foreach (object x in BigComInterface.Ducks)
{
(x as Duck).attribute = value;
}
Jednak przypisanie właściwości jest prawdopodobne (ze względów specyficznych dla aplikacji, które są nieuniknione), aby rzucić wyjątki, z których chcę odzyskać, więc naprawdę chcę spróbować / złapać wokół siebie. A zatem:
foreach (object x in BigComInterface.Chickens)
{
try
{
(x as Chicken).attribute = value;
}
catch (Exception ex)
{
// handle...
}
}
foreach (object x in BigComInterface.Ducks)
{
try
{
(x as Duck).attribute = value;
}
catch (Exception ex)
{
// handle...
}
}
Oczywiście byłoby to o wiele czystsze:
foreach (object x in BigComInterface.Chickens)
{
SetAttribute<Chicken>(x as Chicken, value);
}
foreach (object x in BigComInterface.Ducks)
{
SetAttribute<Duck>(x as Duck, value);
}
void SetAttribute<T>(T x, System.Object value)
{
try
{
x.attribute = value;
}
catch
{
// handle...
}
}
Widzisz problem? Mójx wartość może być dowolnego typu, więc kompilator nie może rozwiązać.atrybut. Kurczak i kaczka nie są w żadnym drzewie dziedziczenia i nie mają interfejsu, który ma.atrybut. Gdyby tak było, mógłbym wprowadzić ograniczenie dla tego interfejsuT. Ale ponieważ klasa jest zamkniętym źródłem, nie jest to dla mnie możliwe.
To, czego chcę, w mojej fantazji, jest czymś w rodzaju ograniczenia wymagającego argumentumieć właściwość .attribute niezależnie od tego, czy implementuje dany interfejs. Dowcip,
void SetAttribute<T>(T x, System.Object value) where T:hasproperty(attribute)
Nie jestem pewien, co robić dalej, niż wycinać / wklejać ten mały blok try / catch dla każdego kurczaka, kaczki, krowy, owcy i tak dalej.
Moje pytanie brzmi: Jakie jest dobre obejście tego problemu polegające na wywołaniu określonej właściwości obiektu, gdy interfejs implementujący tę właściwość nie może być znany w czasie kompilacji?