如果我必须猜的话,我会说这个开发者习惯于像Java这样的其他语言,并没有完全意识到C#的标准做法。在Java、Javascript等语言中,“get [Property]”命名法非常常用。C#用属性和索引器替换了这种方法。属性与getter和setter一样强大,但更易于编写和使用。你通常只在以下情况下在C#中看到“Get [something]”:
- 该操作可能足够昂贵,以至于您确实希望强调这不是简单的成员访问(例如
GetPrimeNumbers()
);或者
- 您的集合实际上包括多个索引集合(例如
GetRow(int i)
和GetColumn(int i))
)。即使在这种情况下,更常见的做法也是将每个这些索引集合公开为一个索引类型的属性(“table.Rows[2]
”)。
如果您只在for
循环中访问这些值,则集合应实现IEnumerable<Thing>
,这将使您可以访问LINQ方法和foreach
结构。如果您仍然需要具有基于索引的getter,则应考虑使用自己的接口,该接口扩展了IEnumerable<T>
,但还提供了:
T this[int i] { get; }
这样,您就不会给消费者留下他们可以在此集合中添加
和删除
对象的印象。
更新
我知道这主要是一种风格问题,因为这是有争议的,但我真的认为GetThings
解决方案不是正确的做法。以下策略虽然需要更多的工作,但更符合标准.NET类和框架的设计方式:
public class ThingHolderDataAccess
{
public ThingHolder GetThingHolderForSomeArgs(int arg1, int arg2)
{
var oneThings = GetOneThings(arg1);
var otherThings = GetOtherThings(arg2);
return new ThingHolder(oneThings, otherThings);
}
private IEnumerable<OneThing> GetOneThings(int arg)
{
return new List<OneThing>();
}
private IEnumerable<AnotherThing> GetOtherThings(int arg2)
{
return new List<AnotherThing>();
}
}
public class ThingHolder
{
public IIndexedReadonlyCollection<OneThing> OneThings
{
get;
private set;
}
public IIndexedReadonlyCollection<AnotherThing> OtherThings
{
get;
private set;
}
public ThingHolder(IEnumerable<OneThing> oneThings,
IEnumerable<AnotherThing> otherThings)
{
OneThings = oneThings.ToIndexedReadOnlyCollection();
OtherThings = otherThings.ToIndexedReadOnlyCollection();
}
}
#region These classes can be written once, and used everywhere
public class IndexedCollection<T>
: List<T>, IIndexedReadonlyCollection<T>
{
public IndexedCollection(IEnumerable<T> items)
: base(items)
{
}
}
public static class EnumerableExtensions
{
public static IIndexedReadonlyCollection<T> ToIndexedReadOnlyCollection<T>(
this IEnumerable<T> items)
{
return new IndexedCollection<T>(items);
}
}
public interface IIndexedReadonlyCollection<out T> : IEnumerable<T>
{
T this[int i] { get; }
}
#endregion
使用上述代码可能看起来像这样:
var things = _thingHolderDataAccess.GetThingHolderForSomeArgs(a, b);
foreach (var oneThing in things.OneThings)
{
}
foreach (var anotherThing in things.OtherThings)
{
}
var specialThing = things.OneThings[c];
IEnumerable<T>
而不是例如List<T>
! - Dan TaoIList<T>
接口或甚至是T[]
的所有其他功能(它允许你设置项,而不仅仅是获取它们)时,这确实很令人沮丧。这实际上是我在一段时间前在我的一个旧问题中询问的内容。 - Dan Tao