2011-03-15 32 views
1

我試圖做類似下面的...獲取對象的子屬性根據病情

 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。所以我正在尋找一種通用方法,可以根據提供的屬性名稱和「源」對象來提取值。

+1

你爲什麼不使用正確的OOP在這種情況下?爲什麼不只是'source.animal.feedDate',然後'source.animal'將任一類型的類型dog'的''cat'or(或別的東西你還沒有加入。) – 2011-03-15 11:36:59

+0

@Lasse五卡爾森,OP已經表示這些是「我無法控制的界面」。 – 2011-03-15 11:41:03

回答

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(); 

或者,如果成員名稱(進料時間)是動態的,太:

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
 if (source.GetType() == typeof(cat)) 
      return source.cat.feedDate ?? string.Empty; 
     if (source.GetType() == typeof(dog)) 
      return source.dog.feedDate ?? string.Empty; 
2

如果只有一個你需要做的這個地方,然後Reflection和/或dynamic將運行良好。

但是,如果您發現自己在整個代碼中都這樣做,則可能需要考慮在您無法控制的類周圍編寫自己的適配器。然後你可以使用多態性(你可以用CatAdapter和DogAdapter後代定義一個基本AnimalAdapter,然後編寫使用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; } } 
} 

如果,當貓或狗對象最初創建的,你知道它是(例如,如果你有一個實例化一個貓一個代碼路徑,而另一個實例狗),那麼你可以只然後創建你的包裝。但是,如果你給一個「源」對象,如你的榜樣,只是給你一個基類(或只是一個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"); 
}