[英]Why return Interfaces eg IEnumerable, IList - example of refactoring
問題:我是否有這個例子?
返回接口的原因是:
Try1:
public class Thing
{
public string name { get; set; }
public int age { get; set; }
public IList<Thing> giveMeAllThings()
{
IList<Thing> listOfThings = new List<Thing>();
Thing thing1 = new Thing { name = "phone", age = 3 };
Thing thing2 = new Thing { name = "waterbottle", age = 2 };
Thing thing3 = new Thing { name = "pinecone", age = 17 };
listOfThings.Add(thing1);
listOfThings.Add(thing2);
listOfThings.Add(thing3);
return listOfThings;
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void UnitTestThings()
{
Thing thing = new Thing();
IEnumerable<Thing> listOfThings = thing.giveMeAllThings();
Assert.AreEqual(3, listOfThings.Count()); // linq count
Assert.IsTrue(listOfThings.Any(t => t.name == "phone" && t.age == 3));
Assert.IsTrue(listOfThings.Any(t => t.name == "waterbottle" && t.age == 2));
Assert.IsTrue(listOfThings.Any(t => t.name == "pinecone" && t.age == 17));
}
}
try2。 我發現由於我只需要IEnumerable,所以我可以將其返回。
public IEnumerable<Thing> giveMeAllThings()
{
IList<Thing> listOfThings = new List<Thing>();
Thing thing1 = new Thing { name = "phone", age = 3 };
Thing thing2 = new Thing { name = "waterbottle", age = 2 };
Thing thing3 = new Thing { name = "pinecone", age = 17 };
listOfThings.Add(thing1);
listOfThings.Add(thing2);
listOfThings.Add(thing3);
foreach (Thing t in listOfThings)
yield return t;
}
編輯:因此,如果我需要一種方法而不是另一種方法的列表,則可能返回的最“常規”接口是IList:
public IList<Thing> giveMeAllThings()
{
IList<Thing> listOfThings = new List<Thing>();
Thing thing1 = new Thing { name = "phone", age = 3 };
Thing thing2 = new Thing { name = "waterbottle", age = 2 };
Thing thing3 = new Thing { name = "pinecone", age = 17 };
listOfThings.Add(thing1);
listOfThings.Add(thing2);
listOfThings.Add(thing3);
return listOfThings;
}
[TestMethod]
public void UnitTestThings()
{
Thing thing = new Thing();
IEnumerable<Thing> listOfThings = thing.giveMeAllThings();
Assert.AreEqual(3, listOfThings.Count()); // linq count
}
[TestMethod]
public void UnitTestThingsWhereINeedAnActualList()
{
Thing thing = new Thing();
IList<Thing> listOfThings = thing.giveMeAllThings();
Assert.AreEqual(3, listOfThings.Count); // List count
}
返回接口的原因是:
這樣做的主要原因是,通過返回最可能的“通用”目的接口,您可以在以后將內部實現更改為“更好”的東西(即:更高效,更簡單的代碼,無論使用何種條件)方面具有更大的靈活性。 ,而不會破壞您的公共API。
例如,如果從IList<T>
切換到IEnumerable<T>
,則可以切換代碼以使用迭代器( yield return
)而不是集合。 您可能會決定使用其他集合(而不是List<T>
)在您的代碼中更好地工作,然后切換到該集合。 如果第二個集合未實現IList<T>
,則將需要您更改公共API。
那么,你可以返回ICollection<Thing>
具有.Count
, Thing[]
具有.Length
,或IEnumberable<Thing>
其具有LINQ擴展方法.Count()
如果只需要元素計數,則不一定需要IList<Thing>
。
使用接口或基本返回類型還表明了打算如何使用返回類型的意圖。
我傾向於大多數時候使用IEnumerable<T>
。
我考慮在需要索引時使用數組(或IList<T>
)。
IEnumerable比IList不夠具體。 我嘗試返回仍然可以使用的最具體的東西。
假設我要返回IDictionary,那么有返回的誘惑:
IEnumerable<ICollection<KeyValuePair<Key, Value>>
但是,我認為這並不能准確地描述正在發生的事情,盡管它的具體含義不如:
IDictionary<Key, Value>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.