前言 :
写程序难免,会遇到要使用自定义函式来作对象数组转型。
写了一个对象来做这个动作,跟大家分享。
说明 :
这个对象的特点为:
1. 使用到才转型。不会在内存,建立整个转型后的数组副本。
2. 可在转型时加入参数。
使用范例 :
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[] userArray = new User[2]; userArray[0] = new User(); userArray[0].LastName = "Chou"; userArray[0].FirstName = "Clark"; userArray[1] = new User(); userArray[1].LastName = "AAAA"; userArray[1].FirstName = "BBBBB"; IEnumerable<Data> dataList = CreateDataList(userArray, "★★★★★"); foreach (Data data in dataList) { Console.WriteLine(data.DisplayName); } Console.WriteLine(""); Console.WriteLine("End"); Console.ReadLine(); } static IEnumerable<Data> CreateDataList(IEnumerable<User> userList, string decorator) { return new CastingEnumerable<Data, User>(userList, delegate(User user) { return CreateData(user, decorator); }); } static Data CreateData(User user, string decorator) { Data data = new Data(); data.DisplayName = decorator + user.LastName + "." + user.FirstName + decorator; return data; } } }
程序代码 :
namespace CLK.Collections { public class CastingEnumerable<TResult, TSource> : IEnumerable<TResult> { //Properties private readonly IEnumerable<TSource> _sourceEnumerable; private CastingEnumerableDelegate<TResult, TSource> _enumerableDelegate; // Construction public CastingEnumerable(IEnumerable<TSource> sourceEnumerable, CastingEnumerableDelegate<TResult, TSource> enumerableDelegate) { Require#region Require if (sourceEnumerable == null) throw new ArgumentNullException(); if (enumerableDelegate == null) throw new ArgumentNullException(); #endregion _sourceEnumerable = sourceEnumerable; _enumerableDelegate = enumerableDelegate; } // Member public IEnumerator<TResult> GetEnumerator() { return new CastingEnumerator<TResult, TSource>(_sourceEnumerable.GetEnumerator(), _enumerableDelegate); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } }
namespace CLK.Collections { public class CastingEnumerator<TResult, TSource> : IEnumerator<TResult> { //Properties private readonly IEnumerator<TSource> _sourceEnumerator; private readonly CastingEnumerableDelegate<TResult, TSource> _enumerableDelegate; private TResult _currentResult = default(TResult); // Construction public CastingEnumerator(IEnumerator<TSource> sourceEnumerator, CastingEnumerableDelegate<TResult, TSource> enumerableDelegate) { Require#region Require if (sourceEnumerator == null) throw new ArgumentNullException(); if (enumerableDelegate == null) throw new ArgumentNullException(); #endregion _sourceEnumerator = sourceEnumerator; _enumerableDelegate = enumerableDelegate; } public virtual void Dispose() { _sourceEnumerator.Dispose(); _currentResult = default(TResult); } // Member public TResult Current { get { return _currentResult; } } object System.Collections.IEnumerator.Current { get { return this.Current; } } public bool MoveNext() { if (_sourceEnumerator.MoveNext() == true) { _currentResult = _enumerableDelegate(_sourceEnumerator.Current); return true; } return false; } public void Reset() { _sourceEnumerator.Reset(); _currentResult = default(TResult); } } }
public delegate TResult CastingEnumerableDelegate<TResult, TSource>(TSource source);
相关资料 :
http://stackoverflow.com/questions/504729/how-do-i-cast-a-listt-effectively
http://msdn.microsoft.com/zh-tw/library/0yw3tz5k.aspx