根据条件获取对象子属性

时间:2011-03-15 11:26:08

标签: c# properties

我正在尝试做以下事情......

       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;
猫和狗可以是任何东西,但总会有feedDate属性,但它们实现了我无法控制的不同接口。

是否有更好的方法来编写此代码,以便更可重用?可能还有更多属性,例如source.cat.napTime和source.dog.napTime。所以我正在寻找一种通用的方法,可以根据提供的属性名称和'源'对象来获取值。

3 个答案:

答案 0 :(得分:2)

如果您只需要一个地方,那么Reflection和/或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; } }
}

如果在最初创建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 :(得分:1)

可能是这样的:

// 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);
}

答案 2 :(得分:0)

      if (source.GetType() == typeof(cat)) 
            return source.cat.feedDate ?? string.Empty;
      if (source.GetType() == typeof(dog)) 
            return source.dog.feedDate ?? string.Empty;