Получить подчиненное свойство объекта на основе условия - PullRequest
1 голос
/ 15 марта 2011

Я пытаюсь сделать что-то вроде следующего ...

       if (source.Type == 'cat')
            return source.cat.feedDate == null 
                ? "" 
                : source.cat.feedDate.Value;
        else
            return source.dog == null 
                ? "" 
                : source.dog.feedDate== null 
                    ? "" 
                    : source.dog.feedDate.Value;

cat и dog могут быть чем угодно, но всегда будут иметь свойство feedDate, но они реализуют разные интерфейсы, которые я не могу контролировать.

Есть ли лучший способ написать этот код, чтобы его можно было многократно использовать? также может быть больше свойств, таких как source.cat.napTime и source.dog.napTime. Поэтому я ищу универсальный метод, который может извлечь значение на основе предоставленного имени свойства и объекта «источник».

Ответы [ 3 ]

2 голосов
/ 15 марта 2011

Если вам нужно сделать только одно место, то Отражение и / или 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");
}
1 голос
/ 15 марта 2011

может быть что-то вроде:

// get .dog. etc
var prop = source.GetType().GetProperty(source.Type);
dynamic subObj = prop == null ? null : prop.GetValue(source,null);
return (subObj == null || subObj.feedDate == null) ? ""
         : subObj.feedDate.Value.ToString();

Или если имя члена (feedTime) тоже динамическое:

static object Get(dynamic source, string memberName)
{
    var prop = source.GetType().GetProperty(source.Type);
    object subObj = prop == null ? null : prop.GetValue(source, null);
    var subProp = subObj == null ? null : subObj.GetType().GetProperty(memberName);
    return subProp == null ? null : subProp.GetValue(subObj, null);
}
0 голосов
/ 15 марта 2011
      if (source.GetType() == typeof(cat)) 
            return source.cat.feedDate ?? string.Empty;
      if (source.GetType() == typeof(dog)) 
            return source.dog.feedDate ?? string.Empty;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...