[.NET] CastingEnumerable
前言 :
写程式难免,会遇到要使用自订函式来作物件阵列转型。
写了一个物件来做这个动作,跟大家分享。
说明 :
这个物件的特点为:
1. 使用到才转型。不会在记忆体,建立整个转型后的阵列副本。
2. 可在转型时加入参数。
使用范例 :
view source
01 namespace CLK.Collections.ConsoleApplication
02 {
03 public class User
04 {
05 public string LastName = string.Empty;
06
07 public string FirstName = string.Empty;
08 }
09
10 public class Data
11 {
12 public string DisplayName = string.Empty;
13 }
14
15 class Program
16 {
17 static void Main(string[] args)
18 {
19 User[] userArray = new User[2];
20
21 userArray[0] = new User();
22 userArray[0].LastName = "Chou";
23 userArray[0].FirstName = "Clark";
24
25 userArray[1] = new User();
26 userArray[1].LastName = "AAAA";
27 userArray[1].FirstName = "BBBBB";
28
29
30 IEnumerable<Data> dataList = CreateDataList(userArray, "★★★★★");
31 foreach (Data data in dataList)
32 {
33 Console.WriteLine(data.DisplayName);
34 }
35 Console.WriteLine("");
36
37
38 Console.WriteLine("End");
39 Console.ReadLine();
40 }
41
42 static IEnumerable<Data> CreateDataList(IEnumerable<User> userList, string decorator)
43 {
44 return new CastingEnumerable<Data, User>(userList, delegate(User user) { return CreateData(user, decorator); });
45 }
46
47 static Data CreateData(User user, string decorator)
48 {
49 Data data = new Data();
50 data.DisplayName = decorator + user.LastName + "." + user.FirstName + decorator;
51 return data;
52 }
53 }
54 }
程式碼 :
view source
01 namespace CLK.Collections
02 {
03 public class CastingEnumerable<TResult, TSource> : IEnumerable<TResult>
04 {
05 //Properties
06 private readonly IEnumerable<TSource> _sourceEnumerable;
07
08 private CastingEnumerableDelegate<TResult, TSource> _enumerableDelegate;
09
10
11 // Construction
12 public CastingEnumerable(IEnumerable<TSource> sourceEnumerable, CastingEnumerableDelegate<TResult, TSource> enumerableDelegate)
13 {
14 #region Require
15
16 if (sourceEnumerable == null) throw new ArgumentNullException();
17 if (enumerableDelegate == null) throw new ArgumentNullException();
18
19 #endregion
20 _sourceEnumerable = sourceEnumerable;
21 _enumerableDelegate = enumerableDelegate;
22 }
23
24
25 // Member
26 public IEnumerator<TResult> GetEnumerator()
27 {
28 return new CastingEnumerator<TResult, TSource>(_sourceEnumerable.GetEnumerator(), _enumerableDelegate);
29 }
30
31 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
32 {
33 return this.GetEnumerator();
34 }
35 }
36 }
view source
01 namespace CLK.Collections
02 {
03 public class CastingEnumerator<TResult, TSource> : IEnumerator<TResult>
04 {
05 //Properties
06 private readonly IEnumerator<TSource> _sourceEnumerator;
07
08 private readonly CastingEnumerableDelegate<TResult, TSource> _enumerableDelegate;
09
10 private TResult _currentResult = default(TResult);
11
12
13 // Construction
14 public CastingEnumerator(IEnumerator<TSource> sourceEnumerator, CastingEnumerableDelegate<TResult, TSource> enumerableDelegate)
15 {
16 #region Require
17
18 if (sourceEnumerator == null) throw new ArgumentNullException();
19 if (enumerableDelegate == null) throw new ArgumentNullException();
20
21 #endregion
22 _sourceEnumerator = sourceEnumerator;
23 _enumerableDelegate = enumerableDelegate;
24 }
25
26 public virtual void Dispose()
27 {
28 _sourceEnumerator.Dispose();
29 _currentResult = default(TResult);
30 }
31
32
33 // Member
34 public TResult Current
35 {
36 get
37 {
38 return _currentResult;
39 }
40 }
41
42 object System.Collections.IEnumerator.Current
43 {
44 get
45 {
46 return this.Current;
47 }
48 }
49
50 public bool MoveNext()
51 {
52 if (_sourceEnumerator.MoveNext() == true)
53 {
54 _currentResult = _enumerableDelegate(_sourceEnumerator.Current);
55 return true;
56 }
57 return false;
58 }
59
60 public void Reset()
61 {
62 _sourceEnumerator.Reset();
63 _currentResult = default(TResult);
64 }
65 }
66 }
view source
1 public delegate TResult CastingEnumerableDelegate<TResult, TSource>(TSource source);
摘自 昏睡領域