我正在尝试做以下事情......
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。所以我正在寻找一种通用的方法,可以根据提供的属性名称和'源'对象来获取值。
答案 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;