универсальная функция с ограничением «имеет свойство X»?

У меня есть стороннее приложение с закрытым исходным кодом, которое экспортирует интерфейс COM, который я использую в своем приложении C # .NET через Interop. Этот COM-интерфейс экспортирует многие объекты, которые отображаются как System.Object, пока я не приведу их к соответствующему типу интерфейса. Я хочу назначить свойство всех этих объектов. Таким образом:

foreach (object x in BigComInterface.Chickens)
{
    (x as Chicken).attribute = value;
}
foreach (object x in BigComInterface.Ducks)
{
    (x as Duck).attribute = value;
}

Но присваивание свойства может (по определенным для приложения причинам, которые неизбежны) генерировать исключения, из которых я хочу восстановить, поэтому я действительно хочу попробовать / поймать каждую из них. Таким образом:

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...
    }
}

Очевидно, было бы намного чище сделать это:

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...
    }
}

Видишь проблему? мойx значение может быть любого типа, поэтому компилятор не может разрешить.attribute, Цыпленок и Утка не находятся в каком-либо дереве наследования, и они не разделяют интерфейс, который имеет.attribute, Если бы они сделали, я мог бы наложить ограничение для этого интерфейса наT, Но так как класс с закрытым исходным кодом, для меня это невозможно.

В моей фантазии я хочу что-то вроде ограничения, требующего аргументаиметь свойство .attribute независимо от того, реализует ли он данный интерфейс. Для остроумия,

void SetAttribute<T>(T x, System.Object value) where T:hasproperty(attribute)

Я не уверен, что делать дальше, кроме как вырезать / вставить этот маленький блок try / catch для каждого из Цыпленка, Утки, Коровы, Овцы и так далее.

Мой вопрос: что является хорошим обходным решением для этой проблемы желания вызвать определенное свойство объекта, когда интерфейс, который реализует это свойство, не может быть известен во время компиляции?

Ответы на вопрос(4)

Ваш ответ на вопрос