[Effective C#] 아이템 19: 런타임에 타입을 확인하여 최적의 알고리즘을 사용하라
C# 카테고리의 다른 글
제네릭의 인스턴스화는 런타임의 타입을 고려하지 않고 컴파일 타임의 타입만을 고려한다.
따라서 제네릭을 사용하면 구체적인 타입이 주는 장점을 잃게 되고, 타입별로 최적화된 알고리즘을 사용할 수 없게 된다.
밑의 코드는 IEnumerable
public sealed class ReverseEnumerable<T> : IEnumerable<T>
{
public class ReverseEnumerator : IEnumerator<T>
{
int currentIndex;
IList<T> collection;
public ReverseEnumerator(IList<T> srcCollection)
{
collection = srcCollection;
currentIndex = collection.Count;
}
// IEnumerator<T> 멤버
public T Current => collection[currentIndex];
// IDisposable 멤버
public void Dispose()
{
// 생략
}
// IEnumerator 멤버
object System.Collections.IEnumerator.Current => this.Current;
public bool MoveNext() => --currentIndex >= 0;
public void Reset() => currentIndex = collection.Count;
}
IEnumerable<T> sourceSequence;
IList<T> originalSequence;
public ReverseEnumerable(IEnumerable<T> sequence)
{
sourceSequence = sequence;
}
// IEnumerable<T> 멤버
public IEnumerator<T> GetEnumerator()
{
if(originalSequence == null)
{
originalSequence = new List<T>();
foreach (T item in sourceSequence)
originalSequence.Add(item);
}
return new ReverseEnumerator(originalSequence);
}
// IEnumerable 멤버
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator() =>
this.GetEnumerator();
}
ReverseEnumerable
그러나 매개변수로 전달한 IEnumerable
따라서 IList
public ReverseEnumerable(IEnumerable<T> sequence)
{
sourceSequence = sequence;
originalSequence = sequence as IList<T>;
}
public ReverseEnumerable(IList<T> sequence)
{
sourceSequence = sequence;
originalSequence = sequence;
}
ReverseEnumerable
(IList
이외에도 입력 시퀀스가 ICollection
또한 string의 경우 IList
이와 같이 제네릭을 사용하면서 각 타입들의 고유 특성을 활용하면 재사용성이 높으면서도 개별 타입에 최적화된 코드를 작성할 수 있다.
댓글남기기