2015-08-17 19 views
2

信息: IDogShelter和ICatShelter都從IAnimalShelter繼承。在派生對象中使用比父定義的更強類型列表

接下來,我有Cat和Dog類,它們都實現並擴展了IAnimal。

IAnimalShelter has a List<IAnimal> called Animals. 
ICatShelter has a List<Cat> called Animals. 
IDogShelter has a List<Dog> called Animals. 

問題: ICatShelter不能有一個列表,名爲動物,因爲IAnimalShelter有它定義爲IAnimal的名單。 VS說要使用「新」關鍵字。所以我只是把它拿走,而沒有IAnimalShelter上的IAnimal列表。

所以 - 我有一個名爲GetAnimalShelters()的方法,它返回IAnimalShelter的列表。然後,我希望能夠遍歷避難所中的每個IAnimal,但不能因爲IAnimalShelter沒有IAnimal列表。這使我不得不將結果投入ICatShelter或IDogShelter以迭代,但我希望能夠成功地將IAnimal列表添加到IAnimalShelter。我怎樣才能做到這一點?

例如:

public interface IAnimalShelter 
{ 
    List<IAnimal> Animals { get; set; } 
} 

public interface ICatShelter 
{ 
    List<Cat> Animals { get; set; } 
} 

public interface IDogShelter 
{ 
    List<Dog> Animals { get; set; } 
} 

然後:

List<IAnimalShelter> shelters = GetShelters(search); //Works 
foreach (IAnimalShelter shelter in shelters) 
{ 
    var x = shelter.Animals; 
} 

所以上面,我只想獲得動物的公用部分,我想IAnimalShelter有一個動物屬性,但對於衍生的避難所類型具有更強類型的動物列表。

+0

我不明白需要'List '和'List 「在ICatShelter和IDogShelter中。只是當你初始化'動物'列表只是使它成爲一個'新列表'或'新列表' – chancea

+0

我的推理是,在代碼中有很多其他地方知道他們正在處理貓,比如說,因此喜歡能夠訪問Cat.Whiskers而無需將動物投入列表。 – JamesD

+0

我在最後的機會中與此同時出現,因爲事實證明,我需要在界面之外訪問特定的一個或兩個屬性的時間很少。 – JamesD

回答

1

您的類型IAnimalShelter承諾其Animals屬性將產生一個對象,其方法將接受Animal類型的參數。如果ICatShelter來自IAnimalShelter,則它還必須具有Animals屬性,該屬性可產生一個對象,其對象的Add方法將接受類型爲Animal的參數。

爲了使這個模型工作,你應該定義IShelter<out T> where T:Animal包括IReadOnlyList<T>類型的Animals財產和TryDonate(Animal it)方法,將請求庇護參加一個特別的動物。一個CatShelter : IShelter<Cat>將能夠讓客戶端代碼收到一個可讀的對象列表,保證所有對象都是Cat類型,並且客戶端可能會嘗試向其提交任何種類的動物,儘管Cat以外的其他類型的捐贈不會被添加到列表。

+0

作爲評論我認爲這是唯一的答案,解決了需要通過'IAnimals'迭代'IAnimalShelter',因爲一個普通的老''不會讓你做差異。我認爲這個答案可以通過分離'TryDonate'方法來改善,因爲如果提交者需要這個功能並且使它看起來更復雜,這個問題甚至不清楚。 (也許'IEnumerable'也可以和'IReadOnlyList'一起提到。) – 31eee384

0

這被稱爲泛型。下面的定義應該給你你在找什麼:

public interface IAnimal { } 

public class Cat : IAnimal { } 

public class Dog : IAnimal { } 

public interface IAnimalShelter<T> where T : IAnimal 
{ 
    List<T> Animals { get; set; } 
} 

public interface ICatShelter : IAnimalShelter<Cat> { } 

public interface IDogShelter : IAnimalShelter<Dog> { } 

ICatShelterAnimals屬性爲List<Cat>

實現這樣的類和編譯器是幸福的:

public class CatShelter : ICatShelter 
{ 
    public List<Cat> Animals { get; set; } 
} 
0

使用泛型:

public interface IAnimalShelter<T> where T : IAnimal 
{ 
    List<T> Animals { get; set; } 
} 

public class Cat: IAnimal 
{ 
} 

public interface ICatShelter : IAnimalShelter<Cat> 
{ 
} 

public class CatShelter: ICatShelter 
{ 
    public List<Cat> Animals { get; set; } 
} 

沒有測試它,但是這應該做的伎倆,如果你的ICatShelter犯規添加任何IAnimalShelter你甚至可以放棄它,直接從IAnimalShelter派生CatShelter

相關問題