Если вам нужно сделать только одно место, то Отражение и / или dynamic будет работать хорошо.
Но если вы обнаружите, что делаете это повсюдуваш код, вы можете рассмотреть возможность написания своих собственных адаптеров вокруг классов, которые вы не можете контролировать.Затем вы можете использовать полиморфизм (вы можете определить базовый AnimalAdapter с потомками CatAdapter и DogAdapter, а затем написать код, который использует AnimalAdapter и вызывает для него виртуальные методы).
public abstract class AnimalAdapter {
public abstract DateTime? FeedDate { get; }
public abstract DateTime? NapTime { get; }
}
public class CatAdapter : AnimalAdapter {
private Cat _cat;
public CatAdapter(Cat cat) { _cat = cat; }
public override DateTime? FeedDate { get { return _cat.feedDate; } }
public override DateTime? NapTime { get { return _cat.napTime; } }
}
public class DogAdapter : AnimalAdapter {
private Dog _dog;
public DogAdapter(Dog dog) { _dog = dog; }
public override DateTime? FeedDate { get { return _dog.feedDate; } }
public override DateTime? NapTime { get { return _dog.napTime; } }
}
If, когда Cat или Dogобъект создан изначально, вы знаете, что это такое (например, если у вас есть один путь кода, который создает экземпляр Cat, и другой, который создает экземпляр Dog), тогда вы можете просто создать свою оболочку прямо сейчас.Но если вам дан объект «источник», как в вашем примере, который просто дает вам базовый класс (или просто object
), тогда вы также захотите добавить фабричный метод, который, вероятно, продолжитAnimalAdapter:
public static AnimalAdapter FromAnimal(object animal) {
var cat = animal as Cat;
if (cat != null)
return new CatAdapter(cat);
var dog = animal as Dog;
if (dog != null)
return new DogAdapter(dog);
throw new ArgumentException("Unexpected animal type");
}