考虑到我想封装它们,为我的属性使用接口是不好的做法吗?
public class Order
{
private readonly ICollection<OrderItem> _orderItems;
public IReadOnlyCollection OrderItems => _orderItems; // not possible without ToList
}
没有简单的方法来公开它,因为无法首先使用IReadOnlyCollection
从IEnumerable
转换为ICollection
或ToList
,而无需首先使用private readonly Collection<OrderItem> _orderItems;
复制整个集合。
我应该将其定义为:
private readonly HashSet<OrderItem> _orderItems;
或
private readonly List<OrderItem> _orderItems;
或
callback = CustomJS(args={}, code="""
let geometry = cb_data['geometry'];
let x0 = geometry['x0'];
let x1 = geometry['x1'];
let event = new CustomEvent('MetricSelected', { detail: [x0, x1]});
let elm = document.getElementById('metric_selected');
elm.dispatchEvent(event);
""")
代替?
答案 0 :(得分:1)
您应遵循的规则是私有成员仅对定义它们的类可见,因此您可以将类型定义为List<T>
或Hashset<T>
或Collection<T>
,其他开发人员如果稍后修改类型,则使用您的班级程序集不会受到重大更改的影响。
只要您知道Hasset<T>
vs List<T>
和List<T>
vs Collection<T>
之间的区别,就可以从问题中选择三种替代方案中的一种。
请删除界面ICollection<OrderItem>
作为私有字段的类型,如果您不想在{{1}中调用ToList()
,请使用具体的课程实施。
答案 1 :(得分:0)
您可以编写自己的扩展名以将ICollection转换为IReadOnlyCollection
public static class CollectionExtensions
{
public static IReadOnlyCollection<T> AsReadOnly<T>(this ICollection<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return source as IReadOnlyCollection<T> ?? new ReadOnlyCollectionAdapter<T>(source);
}
sealed class ReadOnlyCollectionAdapter<T> : IReadOnlyCollection<T>
{
ICollection<T> source;
public ReadOnlyCollectionAdapter(ICollection<T> source) { this.source = source; }
public int Count { get { return source.Count; } }
public IEnumerator<T> GetEnumerator() { return source.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
}