1. IEnumerable,IEnumerator
public class MyIEnumerableClass<T> : IEnumerable<T>,IEnumerator<T>
//可迭代类自己实现迭代器
{
private T[] _data;
private int _currentIdex;
public T Current => this[_currentIdex];
object IEnumerator.Current => Current;
public T this[int index]
{
get
{
return _data[index];
}
set
{
_data[index] = value;
}
}
public MyIEnumerableClass(T[] data)
{
_data = data;
_currentIdex = -1;
}
public IEnumerator<T> GetEnumerator()
{
return this;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public bool MoveNext()
{
if (_currentIdex < _data.Length-1)
_currentIdex++;
else
return false;
return true;
}
public void Reset()
{
_currentIdex = 0;
}
public void Dispose()
{
}
}
IEnumerable
接口调用GetEnumerator()
方法视是否为泛型而定,返回一个枚举器IEnumerator
(可以自己实现,或者用yield return
语句,编译器会自己实现)。在foreach
语句中,先调用类中的GetEnumerator()
方法,生成枚举器,然后循环调用MoveNext()
判断bool
值,使用用Current
执行foreach
中的语句。foreach
调用迭代器,但迭代器一旦生成后无法修改迭代类。如果要修改只能用for循环,并调用linq中的ElementAt
方法。
for (int j = start; j < keyValues.Count; j++)
{
item = keyValues.ElementAt(j).Key;
if (keyValues[item] == 0)
continue;
var i = sum - item;
if (i < item)
break;
tempset.Add(item);
keyValues[item]--;
dfs(returnSet, i, keyValues, tempset,j);
keyValues[item]++;
tempset.Remove(item);
}
2. yield return ,yield break
用yield
实现迭代。
public class YieldReturnEnumerableClass<T> : IEnumerable<T>
{
T[] _data;
public YieldReturnEnumerableClass(T[] data)
{
_data = data;
}
public IEnumerator<T> GetEnumerator()
{
int i = 0;
while(true)
{
if (i == _data.Length)
yield break;
yield return _data[i];
i++;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
yield
只能用在IEnumerable,IEnumerator代码块中。
实现交替输出上下操作。
public class MoveGame
{
IEnumerator _moveUp;
IEnumerator _moveDown;
int count;
int maxStep;
public MoveGame(int max)
{
maxStep = max;
_moveDown = moveDown();
_moveUp = moveUp();
count = 0;
}
public IEnumerator moveUp()
{
while (true)
{
Console.WriteLine("move up:{0}", count);
count++;
if (count < maxStep)
yield return _moveDown;
else
yield break;
}
}
public IEnumerator moveDown()
{
while (true)
{
Console.WriteLine("move up:{0}", count);
count++;
if (count < maxStep)
yield return _moveUp;
else
yield break;
}
}
}
class Program
{
static void Main(string[] args)
{
MoveGame move = new MoveGame(10);
IEnumerator ie = move.moveUp();
while (ie.MoveNext())
ie = ie.Current as IEnumerator;
}
}
3. ICollection
Properties
Count | |
IsSynchronized | |
SyncRoot | Gets an object that can be used to synchronize access to the ICollection. |
Methods
CopyTo(Array, Int32) | Copies the elements of the ICollection to an Array, starting at a particular Array index. |
GetEnumerator() | Returns an enumerator that iterates through a collection. |
4. IList
Properties
Count | |
IsFixedSize | Gets a value indicating whether the IList has a fixed size. |
IsReadOnly | Gets a value indicating whether the IList is read-only. |
IsSynchronized | Gets a value indicating whether access to the ICollection is synchronized (thread safe).(Inherited from ICollection) |
Item[Int32] | Gets or sets the element at the specified index. |
SyncRoot | Gets an object that can be used to synchronize access to the ICollection.(Inherited from ICollection) |
Methods
Add(Object) | Adds an item to the IList. |
Clear() | Removes all items from the IList. |
Contains(Object) | Determines whether the IList contains a specific value. |
CopyTo(Array, Int32) | Copies the elements of the ICollection to an Array, starting at a particular Array index.(Inherited from ICollection) |
GetEnumerator() | Returns an enumerator that iterates through a collection.(Inherited from IEnumerable) |
IndexOf(Object) | Determines the index of a specific item in the IList. |
Insert(Int32, Object) | Inserts an item to the IList at the specified index. |
Remove(Object) | Removes the first occurrence of a specific object from the IList. |
RemoveAt(Int32) | Removes the IList item at the specified index. |
5. IDisposable
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
~BaseClass()
{
Dispose(disposing: false);
}
}
void Dispose()
中调用一个线程安全的Dispose方法(通过信号量disposed),并且由于实现了Dispose接口后GC不会主动释放类,还需要实现对GC的调用
6. ISet
每个元素独一无二
7. IDictionary
8. ICompare
Compare(Object, Object)
实现比较方法
9. IEqualityComparer
Equals(T, T)该方法与一般语义下的Equals相同
GetHashCode(T)自定义hashcode
10. ILookup
查询
public static void ILookupExample()
{
// Create a list of Packages to put into an ILookup data structure.
List<Package> packages = new List<Package> { new Package { Company = "Coho Vineyard", Weight = 25.2, TrackingNumber = 89453312L },
new Package { Company = "Lucerne Publishing", Weight = 18.7, TrackingNumber = 89112755L },
new Package { Company = "Wingtip Toys", Weight = 6.0, TrackingNumber = 299456122L },
new Package { Company = "Contoso Pharmaceuticals", Weight = 9.3, TrackingNumber = 670053128L },
new Package { Company = "Wide World Importers", Weight = 33.8, TrackingNumber = 4665518773L } };
// Create a Lookup to organize the packages. Use the first character of Company as the key value.
// Select Company appended to TrackingNumber for each element value in the ILookup object.
ILookup<char, string> packageLookup = packages.ToLookup(
p => Convert.ToChar(p.Company.Substring(0, 1)),
p => p.Company + " " + p.TrackingNumber
);
// Iterate through each value in the ILookup and output the contents.
foreach (var packageGroup in packageLookup)
{
// Print the key value.
Console.WriteLine(packageGroup.Key);
// Iterate through each value in the collection.
foreach (string str in packageGroup)
Console.WriteLine(" {0}", str);
}
// This code produces the following output:
//
// C
// Coho Vineyard 89453312
// Contoso Pharmaceuticals 670053128
// L
// Lucerne Publishing 89112755
// W
// Wingtip Toys 299456122
// Wide World Importers 4665518773
}