наиболее подходящим ответом здесь будет либо реализация общего интерфейса, либо переопределение виртуального метода из общего базового класса, и использование полиморфизма для предоставления реализации (из различных реализующих классов) во время выполнения. Тогда ваш метод становится:
(blah.Handle).AssociatedFeature = requirementTemplate.GetAssociatedFeature();
Если список не является исключительным (то есть существуют другие реализации), то:
var feature = requirementTemplate as IHasAssociatedFeature;
if(feature != null) {
(blah.Handle).AssociatedFeature = feature.GetAssociatedFeature();
}
вы можете делать аналогичные вещи и с левой стороны, или передавать это как контекст:
var feature = requirementTemplate as IHasAssociatedFeature;
if(feature != null) {
feature.SetAssociatedFeature(blah);
}
(при необходимости)
Другой весьма распространенный подход - это switch
на перечислении здесь:
switch(requirementTemplate.FeatureType) {
case ...
}
одна приятная вещь в этом - то, что это может быть или специфичным для типа или экземпляром.