如果我不得不猜测,我会说这个开发人员已经习惯了 Java 等其他语言,并且不完全了解 C# 中的标准实践。“get[Property]”命名法在 Java、javascript 等中被大量使用。C# 用属性和索引器代替了它。属性与 getter 和 setter 一样强大,但更易于编写和使用。您通常在 C# 中看到“Get[something]”的唯一情况是:
- 该操作可能非常昂贵,以至于您真的想开车回家,因为这不是简单的成员访问(例如
GetPrimeNumbers()
),或者
- 您的收藏实际上包括多个索引收藏。(例如
GetRow(int i)
和GetColumn(int i))
。即使在这种情况下,更常见的做法是将这些索引集合中的每一个简单地公开为自身的属性,它是索引类型(“ table.Rows[2]
”)。
如果您仅在循环中访问这些值for
,则该集合应实现IEnumerable<Thing>
,这将使您能够访问 LINQ 方法和foreach
构造。如果您仍然需要基于索引的 getter,您应该考虑使用您自己的接口 extends IEnumerable<T>
,但另外提供:
T this[int i] { get; }
这样,您就不会给消费者留下他们可以Add
和Remove
此集合中的对象的印象。
更新
我知道这主要是风格问题,这是有争议的,但我真的认为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)
{
// do something
}
foreach (var anotherThing in things.OtherThings)
{
// do something else
}
var specialThing = things.OneThings[c];
// do something to special thing