Java Collections.singletonList(T)只返回List<T>一个元素.C#中有类似的东西会返回IList吗?
要回答你的问题,不.遗憾的是,没有内置任何内容,尽管在使用IEnumerable时它通常很有用.你必须自己动手.
更新
这里有一个高效且不可变的SingletonList实现的代码,而不是使用变通方法IList<T>:
用法
SingletonList<int> bling = new SingletonList<int>(10);
Run Code Online (Sandbox Code Playgroud)
码
public class SingletonList<T> : IList<T>
{
private readonly T _item;
public SingletonList(T item)
{
_item = item;
}
public IEnumerator<T> GetEnumerator()
{
yield return _item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
throw new NotSupportedException("Add not supported.");
}
public void Clear()
{
throw new NotSupportedException("Clear not supported.");
}
public bool Contains(T item)
{
if (item == null) return _item == null;
return item.Equals(_item);
}
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null) throw new ArgumentNullException("array");
array[arrayIndex] = _item;
}
public bool Remove(T item)
{
throw new NotSupportedException("Remove not supported.");
}
public int Count
{
get { return 1; }
}
public bool IsReadOnly
{
get { return true; }
}
public int IndexOf(T item)
{
return Contains(item) ? 0 : -1;
}
public void Insert(int index, T item)
{
throw new NotSupportedException("Insert not supported.");
}
public void RemoveAt(int index)
{
throw new NotSupportedException("RemoveAt not supported.");
}
public T this[int index]
{
get
{
if (index == 0) return _item;
throw new IndexOutOfRangeException();
}
set { throw new NotSupportedException("Set not supported."); }
}
}
Run Code Online (Sandbox Code Playgroud)
Array实施IList; 和长度不能经由被修改Add(如ReadOnly是true).
因此,SingletonList<int>可以像以下一样轻松实现:
var slist = new int[] { 5 };
Run Code Online (Sandbox Code Playgroud)
您可能希望将其包装在一起,System.Collections.ObjectModel.ReadOnlyCollection<T>以便无法更改单个值(如果Java Singleton列表的工作方式如此).例如
var slist = new System.Collections.ObjectModel.ReadOnlyCollection<int>(new int[] { 5 });
Run Code Online (Sandbox Code Playgroud)
您还可以创建扩展方法.
public static IList<T> AsSingletonList<T>(this IEnumerable<T> source)
{
foreach (var item in source)
{
return new System.Collections.ObjectModel.ReadOnlyCollection<T>(new T[] { item });
}
return new System.Collections.ObjectModel.ReadOnlyCollection<T>(new T[] { default(T) });
}
Run Code Online (Sandbox Code Playgroud)
或者断言在源中只有一个值:
public static IList<T> AsSingletonList<T>(this IEnumerable<T> source)
{
IList<T> result = null;
foreach (var item in source)
{
if (result != null)
throw new ArgumentOutOfRangeException("source", "Source had more than one value.");
result = new System.Collections.ObjectModel.ReadOnlyCollection<T>(new T[] { item });
}
if (result == null)
throw new ArgumentOutOfRangeException("source", "Source had no values.");
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑:用于ReadOnlyCollection<T>防止单个值的突变.
注意:虽然我认为其他答案是正确的,但List<T>默认情况下容量为10 - 这有点浪费.
public static class IListExtensions
{
public static IList<T> SingletonList<T>(this IList<T> iList, T item)
{
return Enumerable.Range(0, 1).Select(i => item).ToList().AsReadOnly();
// or
var Result = new List<T>();
Result.Add(item);
return Result.AsReadOnly();
}
}
Run Code Online (Sandbox Code Playgroud)