.NET 中的延迟类型转换集合实现
在日常开发中,我们经常需要对对象集合进行类型转换操作。为了提高性能并减少内存占用,可以实现一个按需转换的集合包装器。
该实现具有以下优势:
- 采用延迟执行机制,仅在访问元素时进行转换,避免一次性创建完整的目标集合副本
- 支持在转换过程中传入额外参数,增强灵活性
应用示例
namespace CLK.Collections.ConsoleApplication
{
public class User
{
public string LastName = string.Empty;
public string FirstName = string.Empty;
}
public class Data
{
public string DisplayName = string.Empty;
}
class Program
{
static void Main(string[] args)
{
User[] users = new User[2];
users[0] = new User { LastName = "Chou", FirstName = "Clark" };
users[1] = new User { LastName = "AAAA", FirstName = "BBBBB" };
IEnumerable<Data> dataList = BuildDataCollection(users, "★★★★★");
foreach (Data item in dataList)
{
Console.WriteLine(item.DisplayName);
}
Console.WriteLine("");
Console.WriteLine("End");
Console.ReadLine();
}
static IEnumerable<Data> BuildDataCollection(IEnumerable<User> sourceUsers, string prefix)
{
return new LazyCastCollection(sourceUsers, (user) => TransformUser(user, prefix));
}
static Data TransformUser(User user, string prefix)
{
return new Data
{
DisplayName = prefix + user.LastName + "." + user.FirstName + prefix
};
}
}
}
核心实现
namespace CLK.Collections
{
public class LazyCastCollection : IEnumerable<TResult>
{
private readonly IEnumerable<TSource> _sourceCollection;
private readonly CastTransformDelegate _transformDelegate;
public LazyCastCollection(IEnumerable<TSource> source, CastTransformDelegate transformer)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (transformer == null) throw new ArgumentNullException(nameof(transformer));
_sourceCollection = source;
_transformDelegate = transformer;
}
public IEnumerator<TResult> GetEnumerator()
{
return new LazyCastIterator(_sourceCollection.GetEnumerator(), _transformDelegate);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
namespace CLK.Collections
{
public class LazyCastIterator : IEnumerator<TResult>
{
private readonly IEnumerator<TSource> _sourceIterator;
private readonly CastTransformDelegate _transformDelegate;
private TResult _currentItem = default(TResult);
public LazyCastIterator(IEnumerator<TSource> sourceIterator, CastTransformDelegate transformer)
{
if (sourceIterator == null) throw new ArgumentNullException(nameof(sourceIterator));
if (transformer == null) throw new ArgumentNullException(nameof(transformer));
_sourceIterator = sourceIterator;
_transformDelegate = transformer;
}
public void Dispose()
{
_sourceIterator.Dispose();
_currentItem = default(TResult);
}
public TResult Current => _currentItem;
object System.Collections.IEnumerator.Current => Current;
public bool MoveNext()
{
if (_sourceIterator.MoveNext())
{
_currentItem = _transformDelegate(_sourceIterator.Current);
return true;
}
return false;
}
public void Reset()
{
_sourceIterator.Reset();
_currentItem = default(TResult);
}
}
}
public delegate TResult CastTransformDelegate(TSource source);
