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?

questionAnswers(4)

yourAnswerToTheQuestion